python随机数生成中的意外行为

时间:2011-02-25 01:21:57

标签: python random

我有以下代码:

import random

rand1 = random.Random()
rand2 = random.Random()

rand1.seed(0)
rand2.seed(0)

rand1.jumpahead(1)
rand2.jumpahead(2)

x = [rand1.random() for _ in range(0,5)]
y = [rand2.random() for _ in range(0,5)]

根据jumpahead()函数的文档,我期望xy是(伪)独立序列。但我得到的输出是:

x: [0.038378463064751012, 0.79353887395667977, 0.13619161852307016, 0.82978789012683285, 0.44296031215986331]

y: [0.98374801970498793, 0.79353887395667977, 0.13619161852307016, 0.82978789012683285, 0.44296031215986331]

如果您注意到,第2至第5个数字相同。每次运行代码时都会发生这种情况。

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:4)

rand1.seed(0)
rand2.seed(0)

使用相同的值初始化它们,以便获得相同(非)随机性。使用某些值(如当前的unix时间戳)来播种它,您将获得更好的值。但请注意,如果您使用当前时间同时初始化两个RNG,您当然会从它们获得相同的“随机”值。

更新:刚刚注意到jumpahead()内容:看看How should I use random.jumpahead in Python - 它似乎回答了您的问题。

答案 1 :(得分:1)

我认为有一个bug,python的文档并没有让它尽可能清晰。

你的两个跳跃参数之间的差异是1,这意味着你只能保证获得1个唯一值(这就是发生的事情)。如果你想要更多的值,你需要更大的参数。

编辑:进一步说明

最初,顾名思义,跳头只是在序列中向前跳跃。很明显,在这种情况下,在序列中前方跳跃1或2位不会产生独立的结果。事实证明,在大多数随机数生成器中跳跃是低效的。出于这个原因,python只是近似跳跃。因为它只是近似的,python可以实现更有效的算法。但是,该方法是“假装”向前跳,传递两个相似的整数不会导致一个非常不同的序列。

要获得不同的序列,您需要传入的整数相距很远。特别是,如果你想读取一百万个随机整数,你需要将你的跳跃分开一百万。

作为最后一点,如果你有两个随机数生成器,你只需要跳过其中一个。你可以(而且应该)让对方处于原始状态。