如何生成可重复的随机数序列?

2024-04-26 19:12:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我想要一个函数,它可以生成一个伪随机的值序列,但是该序列在每次运行时都是可重复的。我想要的数据必须在给定的范围内合理地随机分布,不一定是完美的。

我想写一些代码,它将运行性能测试,基于随机数据。我希望每一次测试运行,每台机器上的数据都是相同的,但是我不想因为存储的原因而将随机数据与测试一起发送(可能最终会有很多兆字节)。

random模块的库似乎没有说同一个种子在任何机器上总是给出相同的序列。

编辑:如果你建议我播种数据(如上所述),请提供说明该方法有效的文档,并将在一系列机器/实现上工作。

编辑:MacOSX上的CPython 2.7.1和PyPy 1.7,以及cpython2.7.1和cpython2.52=.2ubuntu似乎给出了相同的结果。尽管如此,没有文件规定这是黑白的。

有什么想法吗?


Tags: 模块数据方法函数代码文档机器编辑
3条回答

文档并没有明确指出,提供一个seed总是能保证得到相同的结果,但是Python基于所使用的算法实现的random保证了这一点。

根据文档,Python使用Mersenne Twister作为核心生成器。一旦这个算法被植入种子,它就不会得到任何会改变后续调用的外部输出,所以给它相同的种子,你就会得到相同的结果。

当然,你也可以通过设置一个种子并生成大量随机数列表并验证它们是否相同来观察这一点,但我理解,我不想只相信这些。

我没有检查过除了CPython之外的其他Python实现,但我非常怀疑它们是否会使用完全不同的算法实现random模块。

有平台差异,所以如果你在不同的平台之间移动代码,我会使用DrRobotNinja描述的方法。

请看下面的例子。我的台式机上的Python(64位Ubuntu,核心i7,Python 2.7.3)提供了以下信息:

> import random
> r = random.Random()
> r.seed("test")
> r.randint(1,100)
18

但是如果我在Raspberry Pi(ARM11上的Raspbian)上运行相同的代码,就会得到不同的结果(对于相同版本的Python)

> import random
> r = random.Random()
> r.seed("test")
> r.randint(1,100)
34

为此,我使用了一个重复的MD5散列,因为散列函数的目的是一个跨平台的一对一转换,所以在不同的平台上总是相同的。

import md5

def repeatable_random(seed):
    hash = seed
    while True:
        hash = md5.md5(hash).digest()
        for c in hash:
            yield ord(c)

def test():
    for i, v in zip(range(100), repeatable_random("SEED_GOES_HERE")):
        print v

输出:

184 207 76 134 103 171 90 41 12 142 167 107 84 89 149 131 142 43 241 211 224 157 47 59 34 233 41 219 73 37 251 194 15 253 75 145 96 80 39 179 249 202 159 83 209 225 250 7 69 218 6 118 30 4 223 205 91 10 122 203 150 202 99 38 192 105 76 100 117 19 25 131 17 60 251 77 246 242 80 163 13 138 36 213 200 135 216 173 92 32 9 122 53 250 80 128 6 139 49 94

本质上,代码将获取种子(任何有效字符串)并重复散列它,从而生成0到255之间的整数。

相关问题 更多 >