【问题标题】:How can C/C++'s rand() generate random numbers so quickly?C/C++ 的 rand() 怎么能这么快生成随机数?
【发布时间】:2014-06-24 18:25:23
【问题描述】:

我的理解是,伪随机数生成器基本上只需要一些数字(种子),用一堆 XOR 和位移对其进行散列,然后吐出一个非常长的数字,从中可以检索余数得到你的“随机”号码。

现在,通常你会使用 time(NULL) 作为 C/C++ 中 rand() 的种子。但是,time(NULL) 仅每秒递增一次,而不是每毫秒递增一次。那么,如果种子仍然是相同的 time(NULL) 值,我如何在不到一秒的时间内循环 rand() 一千次,并且仍然得到不同的数字作为输出?

【问题讨论】:

  • 在循环中调用rand() 之前调用srand(time(NULL));,您会看到输出一秒钟都不会改变。这就是为什么您通常应该只在程序开始时播种一次 RNG。此外,C++11 在 <random> 标头中添加了一堆更好的 RNG。如果你的编译器支持它们,你应该使用它们。
  • 如果您对伪随机数生成器感兴趣,请查看 Donald Knuth 不朽的“计算机编程艺术”。该主题有广泛的报道。

标签: c++ random prng


【解决方案1】:

rand() 使用之前的随机值作为后续调用的新种子。这就是为什么当您从不同的种子值开始时会生成唯一的随机值序列的原因。

【讨论】:

  • 啊,有道理。
  • 虽然它是最清楚的,但我认为它在技术上不一定(或有效)准确。 RNG 有状态,每次调用rand 时,它都会变为“下一个”状态,并从当前状态生成一个伪随机数。
  • "使用之前的随机值作为新的种子。"至少从某种意义上说,播种意味着调用srand()that does not hold
  • @MooingDuck 是的,从技术上讲,只有初始值被称为“种子”。它简化了解释,将生成的随机值视为后续调用的新种子,因为在计算上随机值的使用方式与种子在第一次调用时的使用方式完全相同。 (至少对于线性同余生成器。)
  • @BilltheLizard 如果是这样,rand() 不是 LCG 还是我的 example 错了?
【解决方案2】:

伪数生成器在一定范围内输出一系列确定性的数字,这些数字看起来应该是随机的。

time(NULL) 是所谓的 RNG 种子,它告诉它系列从哪里开始。每个程序只能执行一次。

顺便说一句,rand() 不是现代 C++。请参阅 here 了解原因和替代方法。

【讨论】:

    【解决方案3】:

    C/C++ 编译器通常使用linear congruential generator 表示 rand()。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 2018-03-24
    • 1970-01-01
    相关资源
    最近更新 更多