【问题标题】:Seeding Python's PRNG with a tuple用元组播种 Python 的 PRNG
【发布时间】:2015-07-23 11:50:57
【问题描述】:

我注意到,如果我用一个元组播种 Python 的 PRNG,每次我都会得到不同的结果。即Python 3.4程序:

import random
seed1 = ('Foo', 'Bar')
random.seed(seed1)
print(random.random())

每次运行时打印一个不同的数字。这是因为所取的种子是元组seed1id,每次都不一样?

使用元组作为 PRNG 的种子以获得可重复结果的最佳方法是什么?只是random.seed(str(seed1))吗?

【问题讨论】:

  • 所以您每次调用 random 时都希望得到相同的结果而不是随机结果?
  • @IanAuld,不完全是:每次运行上述程序时,我都想要相同的输出;也就是说,我希望 Python 使用从给定元组生成的相同整数值来为其 Mersenne Twister 播种。
  • 也许这会有所帮助:stackoverflow.com/questions/9023660/…

标签: python python-3.x random prng random-seed


【解决方案1】:

来自之前的question

对于 Python 3.3+,正如@gnibbler 指出的那样, hash() 在运行之间是随机的。它适用于单次运行,但几乎肯定不会跨程序运行(从您提到的文本文件中提取)。

因此,使用 python 2.x,运行 hash('Foo', 'Bar') 通常每次都会在同一台计算机上返回相同的结果,从而为您提供相同的初始种子。在 python 3.3+ 上,对你的元组运行 hash 每次都会给你一个唯一的值。

如果您想获得与 python 3.3+ 一致的结果,请查看hashlib。例如:

import hashlib
import random

seed1 = ('Foo', 'Bar')
text  = u''.join(seed1).encode('utf-8')
sha   = hashlib.sha1(text)
random.seed(sha.hexdigest())
print(sha.hexdigest())
print(random.random())

> python3 random2.py 
eb8fc41f9d9ae5855c4d801355075e4ccfb22808
0.738130097774164
> python3 random2.py 
eb8fc41f9d9ae5855c4d801355075e4ccfb22808
0.738130097774164

> python2 random2.py 
eb8fc41f9d9ae5855c4d801355075e4ccfb22808
0.628422839243
> python2 random2.py 
eb8fc41f9d9ae5855c4d801355075e4ccfb22808
0.628422839243

即您将获得一致的种子,但由于随机模块的实现方式不同,您仍然会获得不同的随机数。

【讨论】:

  • 谢谢:我不介意它在 Python 2 / Python 3.4 中是否不稳定,但有一点我不明白:random.seed(sha.hexdigest()) 正在向random.seed 发送str :为什么从这个str 生成的哈希没有按照文档描述的 Python 3.3+ 的方式随机化?
  • @xnx 我希望我有一个更好的答案(恕我直言,这是个好问题)。提示在于跨版本的每个功能的帮助。在 python3 中,它声明“对于版本 2(默认),如果 a 是 str、字节或字节数组,则使用所有位。对于版本 1,a 的 hash() 被使用。”
【解决方案2】:

有趣。

如果你这样做:

def repeatable_random(seed):
    random.seed(seed)
    while True:
        yield random.random()

for i, v in zip(range(20), repeatable_random(('Foo', 'Bar'))):
    print((i,v))

每次运行随机序列时,您都会得到不同的值。

如果你这样做:

def repeatable_random(seed):
    random.seed(repr(seed))      # Note 'repr' here
    while True:
        yield random.random()

for i, v in zip(range(20), repeatable_random(('Foo', 'Bar'))):
    print((i,v))

在 Python 解释器的不同运行中是同一系列 1=>n。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多