在现代Python版本中(参见http://svn.python.org/projects/python/branches/release32-maint/Lib/random.py),Random.seed尝试使用从/dev/urandom读取的32个字节。如果这样做不起作用,它将使用当前时间:(a
是可选值,可用于显式地种子PRNG。)
if a is None:
try:
a = int.from_bytes(_urandom(32), 'big')
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
random.random()
或另一个模块方法生成随机数,则种子是在导入时设置的。如果随机数由另一个Random实例生成,则种子是在构造该实例时设置的。# Create one instance, seeded from current time, and export its methods
# as module-level functions. The functions share state across all uses
#(both in the user's code and in the Python libraries), but that's fine
# for most programs and is easier for the casual user than making them
# instantiate their own Random() instance.
种子基于时钟或(如果可用)操作系统源。当导入random
模块时,它会创建(因此种子)一个共享的Random
实例,而不是在首次使用时。
参考资料
random.seed(a=None, version=2)
Initialize the random number generator.
If a is omitted or None, the current system time is used. If randomness sources are provided by the operating system, they are used instead of the system time (see the os.urandom() function for details on availability).
random.py源代码(大幅删节):
from os import urandom as _urandom
class Random(_random.Random):
def __init__(self, x=None):
self.seed(x)
def seed(self, a=None, version=2):
if a is None:
try:
a = int.from_bytes(_urandom(32), 'big')
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
# Create one instance, seeded from current time, and export its methods
# as module-level functions. The functions share state across all uses
#(both in the user's code and in the Python libraries), but that's fine
# for most programs and is easier for the casual user than making them
# instantiate their own Random() instance.
_inst = Random()
Mersenne Twister的典型参考实现接受种子,然后在内部(通常在构造函数中)调用this.init_genrand(seed)
如果你这样做并使用一个简单的数字,你将得到与Python使用不同的结果--也许会像我一样想知道为什么。
为了在另一种语言(我的情况下是node.js)中获得与Python相同的结果,您需要一个支持init_by_array
方法的实现,然后用init_by_array([seed])
初始化它。
如果您只是使用一个简单的32位int值,则此示例适用--如果您的种子是其他内容,则Python以不同的方式传递它(例如,大于32位的数字会分割并以32位每个数组元素发送等),但这应该至少可以帮助某些人朝正确的方向前进。
我最终使用的是https://gist.github.com/banksean/300494中的node.js实现,效果非常好。我在npm上找不到符合我需求的实现,可能需要自己添加一个。
random.py
中的seed
访问了什么,谢谢你的帮助!我怎样才能看到seed
只调用了那个?(以便下次自己解决问题)不过很奇怪,因为numpy.random(uint32)
使用了维基百科的初始化方法。 - DanielTuzes_random
的模块中的Random类(根据约定,伴随C模块的通常有一个前导下划线)。我找到了C模块并向后工作:init函数在顶部有文档记录;我看到init_genrand与维基百科匹配(魔数1812433253有所帮助),并全局搜索“init_genrand”以查找调用者。 - tomsuper().seed(a)
追踪到 将整数转换为数组 更容易。 - tom