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

Joe*_*Joe 14 python random cpython

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

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

random模块的库似乎并不表示相同的种子将始终在任何计算机上提供相同的序列.

编辑:如果您打算建议我播种数据(如上所述),请提供说明该方法有效的文档,并将适用于一系列机器/实现.

编辑:Mac OS X上的CPython 2.7.1和PyPy 1.7以及CPython 2.7.1和CPython 2.52 = .2 Ubuntu似乎给出了相同的结果.尽管如此,还没有任何文件以黑白方式规定这一点.

有任何想法吗?

DrR*_*nja 21

为此,我使用了重复的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
Run Code Online (Sandbox Code Playgroud)

输出:

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
Run Code Online (Sandbox Code Playgroud)

本质上,代码将获取您的种子(任何有效的字符串)并重复哈希,从而生成从0到255的整数.


Jop*_*ppe 10

存在平台差异,因此如果您在不同平台之间移动代码,我会选择DrRobotNinja描述的方法.

请看下面的例子.我桌面计算机上的Python(带有Core i7的64位Ubuntu,Python 2.7.3)给出了以下内容:

> import random
> r = random.Random()
> r.seed("test")
> r.randint(1,100)
18
Run Code Online (Sandbox Code Playgroud)

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

> import random
> r = random.Random()
> r.seed("test")
> r.randint(1,100)
34
Run Code Online (Sandbox Code Playgroud)

  • 当我写这个问题时,我没有添加链接到我对这个问题的答案,所以这里是:/sf/answers/1861443321/基本上,问题是你不用一个初始化生成器整数,但有一些其他值必须首先进行哈希处理(这是平台相关的部分). (4认同)

Ole*_*ksi 6

为随机数生成器指定种子.如果您提供相同的种子,您的随机数也应该相同.

http://docs.python.org/library/random.html#random.seed

  • @Joe它没有被定义,因为这是种子的正式**定义**的一部分.没有伪随机算法可以使用相同的种子给出不同的结果,这是不可能的.我想他们可以提一下,但他们可能认为这对每个人都很明显. (3认同)
  • 我和其他人一样有猜想,我来到这里是因为我不能用事实来支持我的假设.我们是否保证始终使用相同的算法? (3认同)
  • 您是否尝试过使用相同的种子并观察输出? (2认同)

cau*_*ima 6

也是一个答案,为什么这个答案的例子确实在不同的机器上产生不同的输出:

这是因为当播种随机发生器时,种子必须是整数.如果使用某个非整数对生成器进行种子处理,则必须先对其进行哈希处理.哈希函数自己不是平台独立的(显然至少不是所有这些,如果你知道更多,请纠正我).

所以要把它们全部组合在一起:Python使用伪随机数生成器.因此,当从相同状态开始时,所产生的随机数序列将始终相同,与平台无关.它只是一种确定性的算法,没有来自外界的进一步输入.

这意味着:只要您使用相同的状态初始化随机生成器,它将生成相同的数字序列.可以使用相同的整数种子或通过保存并重新应用旧状态(random.getstate()和random.setstate())来完成相同的状态.


Lia*_*m M 5

使用random.seed(...)您可以生成可重复的序列.示范:

import random

random.seed(321)
list1 = [random.randint(1,10) for x in range(5)]

random.seed(321)
list2 = [random.randint(1,10) for x in range(5)]

assert(list1==list2)
Run Code Online (Sandbox Code Playgroud)

这是因为random.seed(...)不是真正随机的:它是伪随机的,因此在给定初始起始条件"种子"的情况下,通过置换某个状态机来产生连续数.


And*_*ark 5

文档没有明确说明提供种子将始终保证相同的结果,但这可以通过Python基于所使用的算法实现随机来保证.

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

当然,您也可以通过设置种子并生成大量随机数并验证它们是相同的来观察这一点,但我理解不想单独信任它.

我没有检查除CPython之外的其他Python实现,但我高度怀疑他们是否会使用完全不同的算法实现随机模块.


Rus*_*ove 5

如果随机数的质量不如跨平台的可重复性那么重要,您可以使用传统的线性同余生成器之一:

class lcg(object):
    def __init__( self, seed=1 ):
        self.state = seed

    def random(self):
        self.state = (self.state * 1103515245 + 12345) & 0x7FFFFFFF
        return self.state
Run Code Online (Sandbox Code Playgroud)

由于这是使用整数运算在程序中编码的,因此它应该在任何合理的平台上具有确定性的可重复性.