随机漫步(Random walk),也称随机游走,是一种数学统计模型,它由一连串轨迹所组成,其中每一次都是随机的,它能用来表示不规则的变动形式,如同一个人乱步所形成的随机记录。气体或液体中分子活动的轨迹等也可作为随机漫步的模型。这个概念在1905年由卡尔·皮尔逊首次提出,目前已在许多领域中得到应用,如生态学、经济学、心理学、计算科学,物理学、化学和生物学等。

随机漫步有很多实际用途。比如,分子运动是随机的,就可以用随机漫步模拟扩散作用。一会将要编写的代码能模拟现实中的很多情形。
先附上一张艺术感十足的随机漫步可视化图表
rw_dev_8.png

下面我们来编写随机漫步的代码。

一、创建随机漫步,便于调用

1. 创建随机漫步的类RandomWalk()

# -*- coding:utf-8 -*-
from random import choice


class RandomWalk():
    def __init__(self, num_points=5000):
        self.num_points = num_points
        # 随机漫步从(0,0)开始
        self.x_values = [0]
        self.y_values = [0]

将默认点数设置为5000,这大到足够生成有趣的模式,同时确保能快速模拟随机漫步。

2. 完成漫步

--snip--

    def fill_walk():
        """完成漫步"""
        while len(self.x_values) < self.num_points:
            # 前进方向和距离
            x_direction = choice([1, -1])
            x_distance = choice([0, 1, 2, 3, 4])
            x_step = x_direction * x_distance

            y_direction = choice([1, -1])
            y_distance = choice([0, 1, 2, 3, 4])
            y_step = y_direction * y_distance

            # 忽略原地踏步
            if x_step == 0 and y_step == 0:
                continue
            # 漫步一步
            self.x_values.append(self.x_values[-1] + x_step)
            self.y_values.append(self.y_values[-1] + y_step)

二、可视化随机漫步

为保持结构清晰,我们选择新建一个rw_visual.py通过导入刚才创建的类的方式进行可视化。

# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
from random_walk import RandomWalk

rw = RandomWalk()
rw.fill_walk()

plt.scatter(rw.x_values, rw.y_values, s=15)
plt.show()

效果如下:
random_walk_once.png

三、优化输出

  1. 多次随机漫步

每次随机漫步生成的模式都不同,便于探索生成的各种模式,我们可以通过while循环实现多次漫步。

# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
from random_walk import RandomWalk

while True:
    rw = RandomWalk()
    rw.fill_walk()

    plt.scatter(rw.x_values, rw.y_values, s=15)
    plt.show()
    judge = input("If continue?(y/n)")
    if judge=='n':
        break
  1. 改变样式

为突出随机漫步的重要特征,可以为其改变样式。

# -*- coding:utf-8 -*-
import matplotlib.pyplot as plt
from random_walk import RandomWalk

while True:
    # 增加点数
    rw = RandomWalk(50000)
    rw.fill_walk()

    # 调节尺寸
    plt.figure(dpi=128, figsize=(10, 6))

    # 使用颜色映射来反映各点的先后顺序
    points = list(range(rw.num_points))
    plt.scatter(rw.x_values, rw.y_values, c=points, cmap=plt.cm.Blues, s=15)

    # 突出起点和终点
    plt.scatter(0, 0, c='g', s=100)
    plt.scatter(rw.x_values[-1], rw.y_values[-1], c='r', s=100)

    # 隐藏坐标轴
    plt.axes().get_xaxis().set_visible(False)
    plt.axes().get_yaxis().set_visible(False)

    plt.show()
    judge = input("If continue?(y/n)")
    if judge == 'n':
        break

函数figure()用于指定图表的宽度、高度、分辨率和背景色。形参figsize接收一个元组表示宽高,单位为英寸。形参dpi接收屏幕分辨率。

plt.axes().get_xaxis().set_visible(False)
plt.axes().get_yaxis().set_visible(False)

分别用于隐藏x轴和y轴。

最终结果如下:
rw_dev.png

最后修改:2019 年 07 月 07 日 12 : 10 AM
如果觉得我的文章对你有用,请随意赞赏