使用随机模块生成一维随机游走

Generating a 1D random walk with random module

我试图用 random 模块在 1D 中生成随机游走。如果某个时刻的位置是x,那么下一个位置可以等概率地是x+1x-1。我需要在 100 次移动后找到最终位置 (start=0)。

我开发了下面的代码,但我不确定应该如何定义这些选项之间的等概率。

import random
def randomwalk1D(n):
    x = 0
    start = x
    xposition = [start]
    probabilities = [0.5, 0.5]
    for i in range(1, n + 1):
        step = random.choice(probabilities)
        if step > probabilities[0]:
            x += 1
        elif step < probabilities[1]:
            x -= 1
        xposition.append(start)
    return xposition

函数 return 只是将结果归零(输入 n = 100)。我只想使用 random 模块。有人可以建议从这里做什么吗?

我认为您的代码中有两个不同的问题导致了您所看到的结果:

  • random.choice(probabilities) 表达式的结果始终为 0.5。这样,以下两个 if 语句将永远不会被触发,并且 x 始终保持相同的值。
  • 当您使用 xposition.append 追加步骤时,您追加的是起始值,该值在 for 循环的迭代中也保持不变,因此只会追加 0。

此外,对于 random.choice 的实际作用可能存在一些混淆。
它接受一个可迭代对象,并统一选择其中一项进行输出。因为你给了它 [0.5, 0.5] 这意味着,你只能得到 0.5 作为输出。或许您可以使用 random.uniform(0, 1) 作为 step 生成一个均匀随机数。这样你就可以根据 step >= 0.5step < 0.5.

来决定走路的方向了

您的代码有两个问题:

  1. 您需要将 -11 的选择传递给 random.choice(),而不是这些选择的权重。您还可以摆脱与 probabilities 中的元素和采样步骤的直接比较。如果要加权采样,use numpy.random.choice.
  2. 您将 start 重复添加到 xpositions 列表中,即使您从未更新过它。要解决,请改为附加 x,它表示实际的当前位置。

这是解决这两个问题的代码片段。

import random
def randomwalk1D(n):
    x = 0
    start = x
    xposition = [start]
    probabilities = [-1, 1]
    for i in range(1, n + 1):
        x += random.choice(probabilities)
        xposition.append(x)
    return xposition

print(randomwalk1D(100))

已经发布了一些很好的答案,所以我要补充一点,可以进行一些优化:

import random
def randomwalk1D(n):
    x = 0
    xposition = [x]
    for _ in range(n):
        step = random.randint(0,1)
        if step:
            x += 1
        else:
            x -= 1
        xposition.append(x)
    return xposition

这将删除 start,因为我们可以简单地定义 x = 0,并且由于您希望列表以此值开头,因此实例化列表时包含 [x]

    x = 0
    xposition = [x]

我们使用 for _ in range(n) 而不是 for i in range(1, n + 1):。这会循环相同的次数,但从默认值 0 开始。因为没有使用变量 i,我们使用 _ 这是一个标准,表示该值无关紧要,我们只想循环一定次数。

    for _ in range(n):

我们使用 random.randint(0,1) 而不是数字列表和 random.randchoice。此范围包含在内,因此它将 return 0 或 1。

step = random.randint(0,1)

然后,因为1是“真实的”,我们可以简单地测试if step:来测试是否为1,否则使用else:

        if step:
            x += 1
        else:
            x -= 1
>>> randomwalk1D(10) 
[0, 1, 2, 3, 2, 3, 4, 3, 4, 3, 4]

编辑:

如果需要加权数,可以对代码做如下修改:

        choices = (0,1)
        weights = (10,1)
        step = random.choices(choices, weights=weights).pop()

step 将被定义为 0 或 1,其中 0 的可能性是 1 的 10 倍。