设置 random.seed() 以重新创建模拟行为和选择种子的影响

Impact of setting random.seed() to recreate a simulated behaviour and choosing the seed

我正在 python 中进行完全确定性的调度模拟。所以,当我有相同的输入和参数时,我总是得到相同的输出。

现在我想随机化模拟的初始启动状态并比较两个(或更多)不同模拟参数的输出。为了比较 "same randomized initial starting state",我想为 random.seed() 设置一个初始值,对于不同调度程序的所有比较,该值应该保持不变。此外,我想查看一个调度程序在不同初始状态下的行为,因此我必须更改 random.seed()。这当然是我必须为所有调度程序做的。

现在我的问题是,种子对随机生成器的 "randomness" 有什么影响?例如,我选择 1 号种子还是 100 号种子有关系吗?而且因为我想为同一个调度程序使用不同的种子并将其与其他调度程序进行比较,我可以简单地使用例如种子 1 到 10 或者我的种子必须是 "more random"?

为了清楚起见,我使用随机生成器在不同的核心上分配初始任务,并将输出与 "my optimal (deterministic) initial distribution" 进行比较。我想用我选择的种子获得广泛的不同分布。

你选择的种子应该无关紧要

如果正确生成了伪随机数生成器,那么任何种子都应该生成随机分布的数字。

来自Wikipedia

For a seed to be used in a pseudorandom number generator, it does not need to be random. Because of the nature of number generating algorithms, so long as the original seed is ignored, the rest of the values that the algorithm generates will follow probability distribution in a pseudorandom manner.

尽管您选择的种子在理论上并不重要,但在实践中可能很重要。

  1. 有许多 PRNG,给定的播种策略将为其生成相关的伪随机数序列。例如,在大多数版本的 PCG 中,从仅高位不同的种子生成的两个序列 will be highly correlated ("Subsequences from the same generator"). Another example, this time involving Unity's PRNG, is found in "A Primer on Repeatable Random Numbers".
  2. 如果您选择顺序种子,或仅略有不同的种子,则使用种子初始化 PRNG 状态的方式可能很重要。我不知道 base Python 的 random.seed(integer_seed) 如何避免这个问题,但是如果两个 Mersenne Twister 状态只有一位不同,它们产生的两个序列将相互关联,并且它将需要 millions of numbers 来消除这种相关性。许多其他 PRNG 也会出现类似的问题,尤其是线性 PRNG。
  3. 与其他常用的 PRNG(通常为 32 到 128 位)相比,Mersenne Twister 具有巨大的状态(大约 20,000 位)。除非你用与其状态一样大的种子为 PRNG 播种,否则会有一些 PRNG 状态永远不会产生(因此一些伪随机数序列永远不会产生)。另请参阅 this question,其中讨论了 Mersenne Twister 播种,这是基础 Python 中使用的算法。

要降低相关伪随机数的风险,您可以使用 PRNG 算法,例如 SFC 和其他所谓的“基于计数器的”PRNG(Salmon 等人,“平行随机数:与 1 一样简单, 2, 3", 2011),支持伪随机数的独立“流”。 (但是请注意,PCG has a flawed notion of "streams".) There are other strategies as well, and I explain more about this in "Seeding Multiple Processes". See also this question.

此外,如果您使用的是 NumPy(这是一个流行的 Python 科学工作库),请注意 NumPy 1.17 引入了 new pseudorandom number generation system; it uses so-called bit generators, such as PCG, and random generators, such as the new numpy.random.Generator. It was the result of a proposal to change the PRNG policy. The NumPy documentation has detailed information on seeding PRNGs in parallel.