这里的困惑在于伪随机数生成器的工作原理。
像 C 的 rand
这样的伪随机数生成器通过使用一个代表当前“状态”的数字来工作。每次调用 rand
函数时,都会对“state”编号进行一些确定性计算,以生成下一个“state”编号。因此,如果给生成器相同的输入(相同的“状态”),它将产生相同的输出。
因此,当您使用 srand(74)
为生成器播种时,它每次都会生成相同的数字字符串。当您使用 srand(75)
为生成器播种时,它将生成不同的数字字符串等。
确保每次输出不同的常用方法是始终提供不同的种子,通常通过使用以秒/毫秒为单位的当前时间为生成器播种来完成,例如srand(time(NULL))
.
编辑:这是演示此行为的 Python session 。这完全在意料之中。
>>> import random
如果我们用相同的数字为生成器播种,它将始终输出相同的序列:
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
如果我们给它一个不同的种子,即使是一个稍微不同的种子,数字将与旧种子完全不同,但如果使用相同的(新)种子,数字仍然相同:
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
我们如何让我们的程序每次都有不同的行为?如果我们提供相同的种子,它的行为将始终相同。我们可以使用 time.time()
函数,每次调用它都会产生不同的数字:
>>> import time
>>> time.time()
1347917648.783
>>> time.time()
1347917649.734
>>> time.time()
1347917650.835
因此,如果我们通过调用 time.time()
继续重新播种,我们每次都会得到不同的数字序列,因为每次的种子都不同:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[60, 75, 60, 26, 19, 70, 12, 87, 58, 2, 79, 74, 1, 79, 4, 39, 62, 20, 28, 19]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[98, 45, 85, 1, 67, 25, 30, 88, 17, 93, 44, 17, 94, 23, 98, 32, 35, 90, 56, 35]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[44, 17, 10, 98, 18, 6, 17, 15, 60, 83, 73, 67, 18, 2, 40, 76, 71, 63, 92, 5]
当然,比不断重新播种更好的是播种一次并从那里继续:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[94, 80, 63, 66, 31, 94, 74, 15, 20, 29, 76, 90, 50, 84, 43, 79, 50, 18, 58, 15]
>>> [random.randint(0, 100) for _ in xrange(20)]
[30, 53, 75, 19, 35, 11, 73, 88, 3, 67, 55, 43, 37, 91, 66, 0, 9, 4, 41, 49]
>>> [random.randint(0, 100) for _ in xrange(20)]
[69, 7, 25, 68, 39, 57, 72, 51, 33, 93, 81, 89, 44, 61, 78, 77, 43, 10, 33, 8]