可能重复:
Why do I always get the same sequence of random numbers with rand()?
我一直在尝试用C语言生成随机数,而且我遇到了一些奇怪的东西。我不知道它是否仅在我的编译器上,但每当我尝试使用rand()函数生成伪随机数时,它会返回一个非常可预测的数字 - 使用参数3.1 +之前生成的数字是准确的。这很难解释,但这是一个例子。
srand(71);
int number = rand();
printf("%d", number);
这将返回270。
srand(72);
int number = rand();
printf("%d", number);
返回273。
srand(73);
int number = rand();
printf("%d", number);
返回277。
srand(74);
int number = rand();
printf("%d", number);
这将返回280。
每八个数字高出4。否则就是3。
这可能不对。我的编译器有问题吗?
编辑:我弄明白了 - 我创建了一个只接种一次的函数,然后我循环rand()
并生成随机数。谢谢大家!
答案 0 :(得分:3)
这里的混乱是关于伪随机数生成器如何工作。
像C&#39 {1}}这样的伪随机数生成器通过一个代表当前状态的数字来工作。每次调用rand
函数时,都会对“状态”进行一些确定性计算。产生下一个州的数字'数。因此,如果给发生器输入相同的输入(相同的状态'),它将产生相同的输出。
因此,当您使用rand
为种子生成种子时,每次都会生成相同的数字字符串。当您使用srand(74)
为生成器播种时,它将生成不同的数字串等。
每次确保不同输出的常用方法是始终提供不同的种子,通常通过用当前时间(以秒/毫秒为单位)播种发生器来完成,例如, srand(75)
。
编辑:这是一个演示此行为的Python会话。完全可以预料到。
srand(time(NULL))
如果我们使用相同的数字为生成器播种,它将始终输出相同的序列:
>>> 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]
答案 1 :(得分:0)
rand()
的每次调用都会返回预定义序列中的下一个数字,其中起始编号是提供给srand()
的种子。这就是为什么它被称为伪 - 随机数生成器,而不是随机数生成器。
答案 2 :(得分:0)
rand()
由pseudo random number generator实现。
由rand()
的连续调用生成的数字分布具有随机数的属性,但订单是预先确定的。
“开始”号码由您提供的种子确定。
你应该只给PRNG一个种子。为其提供多个种子可以从根本上改变发电机的随机性。此外,一遍又一遍地提供相同的种子会消除所有随机性。
答案 3 :(得分:0)
无论实现如何,生成“随机”数字都取决于divergent infinite sequence。无限序列是使用随机函数的种子生成的,由于其性质,它实际上是伪随机的。这将向您解释为什么您的数字实际上非常依赖于您为函数提供的种子。
在一些实现中,序列仅为一个,并且种子是序列的起始成员。在其他情况下,取决于种子存在差异序列。如果没有提供种子,那么种子由内部“时钟”确定。
通过分别执行randValue % upperBound
和randValue + lowerBound
,在使用随机数的上限和下限时,数字会被截断。随机实现与Hash Functions非常相似。根据体系结构,随机值的上限取决于它是否可以执行的最大整数/倍,如果没有被用户设置为低。