这里的困惑在于伪随机数生成器是如何工作的。
像 C 那样的伪随机数生成器rand
通过一个代表当前“状态”的数字来工作。每次rand
调用该函数时,都会对“状态”编号进行一些确定性计算,以生成下一个“状态”编号。因此,如果给定生成器相同的输入(相同的“状态”),它将产生相同的输出。
因此,当您使用 为生成器播种时srand(74)
,它每次都会生成相同的数字串。当您使用 为生成器播种时srand(75)
,它将生成不同的数字字符串等。
确保每次输出不同的常用方法是始终提供不同的种子,通常通过以秒/毫秒为单位的当前时间播种生成器来完成,例如srand(time(NULL))
。
编辑:这是一个演示此行为的 Python 会话。这是完全可以预料的。
>>> 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]