c - Rand() 似乎无法正常工作

标签 c random srand

<分区>

Possible Duplicate:
Why do I always get the same sequence of random numbers with rand()?

我一直在尝试用 C 语言生成随机数,但遇到了一些奇怪的事情。我不知道它是否只存在于我的编译器上,但每当我尝试使用 rand() 函数生成伪随机数时,它都会返回一个非常可预测的数字——准确地说是用前面的参数生成的数字加上 3.125。这很难解释,但这里有一个例子。

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() 然后它生成随机数。谢谢大家!

最佳答案

这里的困惑在于伪随机数生成器的工作原理。

像 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]

关于c - Rand() 似乎无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12466862/

相关文章:

c - 如何在 C 中使用正则表达式查找文件中的一行?

sql-server - SQL Server CHOOSE() 函数与 RAND() 函数的行为异常

c++ - rand() %4000000000UL 只给出小值

visual-studio-2010 - MS VS 2010 srand()无法编译?

c++ - 具有相同种子的 rand() 函数是否会在不同的 PC 上给出相同的随机数?

c++ - 在 Linux 上使用 C/C++ 中的 write() 函数通过 UART Beaglebone Black 写入 70kB

c - 分配给结构成员的值不正确

c++ - 梅森捻线机预热与再现性

c++ - 如何将应用程序与静态库链接+为什么这不起作用

c# - .NET 的 Random() 的实现更改