我在模拟中使用连续的种子(1、2、3、4...)来生成随机数。那么这些接近的种子会使生成的伪随机数也相似吗?
我认为这并不会改变任何事情,但是我在使用Python。
编辑:我进行了一些测试,数字看起来并不相似。但我担心只是通过观察数字无法发现相似性。是否存在随机数生成的理论特征,可以保证不同的种子给出完全独立的伪随机数?
根据定义,种子和生成的随机数之间肯定存在相关性。问题在于随机化算法是否足够产生看起来不相关的结果,您应该学习评估随机性的方法来回答这个问题。
您的担忧是正确的。下面是使用0到9的种子值从微软的C++ rand
函数获得的结果:
38 7719 21238 2437 8855 11797 8365 32285 10450 30612
41 18467 6334 26500 19169 15724 11478 29358 26962 24464
45 29216 24198 17795 29484 19650 14590 26431 10705 18316
48 7196 9294 9091 7031 23577 17702 23503 27217 12168
51 17945 27159 386 17345 27504 20815 20576 10960 6020
54 28693 12255 24449 27660 31430 23927 17649 27472 32640
58 6673 30119 15745 5206 2589 27040 14722 11216 26492
61 17422 15215 7040 15521 6516 30152 11794 27727 20344
64 28170 311 31103 25835 10443 497 8867 11471 14195
68 6151 18175 22398 3382 14369 3609 5940 27982 8047
import random
myrandom = random.SystemRandom
x = myrandom.random # yields a number in [0,1)
dump x out to file...
然后当需要种子时
import random
read x from file...
newseed = int(x*(2**31)) # produce a 32 bit integer
random.seed(newseed)
nextran = random.random()
nextran = random.random()...
如果您担心顺序种子,那么请不要使用顺序种子。建立一个主RNG,使用已知的种子,并从该主RNG中连续获取输出以根据需要为各个子RNG提供种子。
由于您知道主RNG的初始种子,因此如果需要,可以再次完全按照之前的方式运行整个模拟。
masterSeed <- 42
masterRNG <- new Random(masterSeed)
childRNGs[] <- array of child RNGs
foreach childRNG in childRNGs
childRNG.setSeed(masterRNG.next())
endforeach
引用随机模块文档:
关于底层Mersenne Twister核心生成器的一般说明:
- 周期为2 ** 19937-1。
- 它是现存最经过广泛测试的生成器之一。
我更担心我的代码会出问题,而不是我的RNG不够随机。总的来说,你对随机性的直觉感觉可能是错误的 - 即使没有实际存在的模式,人类大脑也很擅长找到模式。
只要你知道由于缺乏随机种子,你的结果不会“安全”,那么你就应该没问题了。
hashlib
中的 SHA1 算法传递种子;该算法旨在将类似的值映射到完全不同的值。 - Fred Foorandom
模块使用更好的算法。 - Mark Ransom