【发布时间】:2018-11-12 17:17:30
【问题描述】:
我有一个简单的 C++ 程序,用来与我的学生演示随机选择数组元素。
像往常一样,我使用srand (time (0)); 播种,然后使用rand() 生成数字。
数组有七个条目,选择的条目是第一个 - 下标 0。
我现在已经在 40 分钟内运行了该程序的 15 次版本,第一个随机生成的数字是 7 的倍数,例如:
1258771276 1258586399 1229409447 1257140997 1256216612 1260855344 1262973026 1266351233
我将程序更改为在播种后选择五个随机数,并且(在生成 7 的初始倍数后),后续数字表现得更好。
我了解“随机”意味着我无法预测数字会有所不同,就像我无法预测它们相同。
我也明白这些是伪随机数。
我也明白 rand() 预计不会是顶级加密随机化。
不过,这种行为太奇怪了,我完全惊呆了。我是否陷入了 C++ 运行时的奇怪裂缝?这是在完全修补到 Mojave 10.14.1 的 MacOS 上使用 Xcode。
【问题讨论】:
-
像 rand() 的(通常)实现这样的线性同余生成器通常会显示这样的伪像 - 这就是为什么您不应该将它们用于任何严肃的应用程序的原因。另一个伪像似乎是生成的数字的前两位始终是 12。如果您必须使用 rand(),那么取中间数字通常可以为您提供“更好”的值。
-
也许这个stackoverflow.com/questions/13445688/…会有所帮助。
-
我同意 Neil 的观点,如果我可以补充的话,C++ rand() 函数非常方便(并且可能作为教师最容易演示),但已被更完整的库函数所取代, cplusplus.com/reference/random
-
看到一个伪随机生成器在播种后总是生成 7 的倍数,但对于序列中的进一步伪随机值没有显示这种异常,这将是相当奇怪的。毕竟,典型的
rand实现通常不会从“继承自先前rand()调用”的状态中辨别出“新播种”状态。如果您观察到类似的情况,我会怀疑种子值存在异常,而不是生成器实现中的异常。但是,rand()实现中的错误仍然可能导致此问题。 -
@AnT:不幸的是,这个生成器就是这种情况。它生成的第一个数字几乎总是具有相同的值(mod 16807)。并且 16807 可以被 7 整除。这就是 OP 遇到这种情况的原因。