【问题标题】:Logic behind the random number generator in C [duplicate]C中随机数生成器背后的逻辑[重复]
【发布时间】:2012-10-14 18:24:05
【问题描述】:

可能重复:
How does a random number generator work?

C 编译器如何决定是否应该在随机数生成函数中生成下一个数字?例如,它总是在给定范围内生成一个新的随机数。这是怎么做到的?

【问题讨论】:

  • 我注意到的问题是每次运行程序时都会生成相同的随机数序列。因此,种子进来了。

标签: c


【解决方案1】:

它通过保持一些状态并在每次调用函数时修改状态来生成下一个数字。这样的函数称为伪随机数生成器。创建 PRNG 的旧方法是线性同余生成器,这很简单:

static int rand_state;
int rand(void)
{
    rand_state = (rand_state * 1103515245 + 12345) & 0x7fffffff;
    return rand_state;
}

如您所见,如果您知道前一个数字,则此方法允许您预测系列中的下一个数字。还有更复杂的方法。

已经为特定目的设计了各种类型的伪随机数生成器。有一些安全的 PRNG,虽然速度很慢,但即使你知道它们是如何工作的也很难预测,还有像 Mersenne Twister 这样的大型 PRNG,它们具有很好的分布特性,因此对于编写 Monte Carlo 模拟很有用。

根据经验,线性同余生成器足以编写游戏(怪物造成多少伤害),但不足以编写模拟。研究人员选择较差的 PRNG 用于他们的项目的历史是丰富多彩的。因此,他们的模拟结果令人怀疑。

【讨论】:

    【解决方案2】:

    它不是编译器,而是一个 C 库,具有生成伪随机(不是真正的随机!)数字的功能。

    通常linear congruential generators 用于此。

    【讨论】:

      【解决方案3】:

      好吧,C 编译器不会做出这样的决定。下一个随机数取决于算法。生成随机数并不是一件容易的事。来看看

      【讨论】:

        【解决方案4】:

        这取决于所讨论的伪随机数生成器 (PRNG) 的具体实现。有很多变体在使用。

        一个常见的例子是linear congruential generators (LCG) 系列。这些由递归关系定义:

           Xn+1n + c (mod m)

        因此,PRNG 中的每个新样本仅由前一个样本以及常数 a、c 和 m 确定。请注意,如 here 所述,a、c 和 m 的选择至关重要。

        LCG 非常简单高效。它们通常用于标准库提供的随机数生成器。然而,它们的统计特性很差,为了更好的随机性,更高级的 PRNG 是首选。

        【讨论】:

          【解决方案5】:

          stackoverflow 中有很多关于此的问题。这里有几个。您可以从这些中获得帮助。

          implementation of rand()

          Rand function in c

          Rand Implementation

          【讨论】:

            【解决方案6】:

            这实际上是一个非常大的话题。一些关键的事情:

            • 随机数生成是在运行时完成的,而不是在编译时。
            • 提供随机性的策略很大程度上取决于(或应该取决于)应用程序。例如,如果您只需要在给定范围内均匀分布的一系列值,则使用线性同余生成器等解决方案。如果您的应用程序与安全/加密相关,您将需要更强大的属性,即您的值既是随机分布的,又是不可预测的。
            • 一个主要挑战是获取“真实”随机性,您可以使用它来播种伪随机生成器(它将真实随机性“拉伸”成任意数量的可用随机性)。一种常见的技术是使用一些不可预测的系统状态(例如,对鼠标位置或按键时间进行采样),然后使用伪随机生成器为整个系统提供随机性。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-06-25
              • 2014-06-10
              • 1970-01-01
              • 2012-12-17
              • 1970-01-01
              相关资源
              最近更新 更多