【问题标题】:Why does the mersenne_twister_engine guarantee certain results?为什么 mersenne_twister_engine 能保证某些结果?
【发布时间】:2019-02-25 23:32:43
【问题描述】:

我在cppreference's article for std::mersenne_twister_engine 上注意到以下内容(例如std::mt19937):

需要连续第 10000 次调用默认构造的 std::mt19937 才能生成值 4123659995

需要连续第 10000 次调用默认构造的 std::mt19937_64 才能生成值 9981545732273789042

假设对标准的这种解释是准确的,那么问题是什么?为什么存在这些保证?这不是非随机吗?

【问题讨论】:

  • 这些是确定性伪随机数生成器。如果没有适当的随机种子,它们不就是这样吗?使用actually random number 播种会产生不可预测的输出。
  • mersenne_twister 根据定义是非随机的。它是一个 PRNG,我认为要求是强制 MT 进行正确的实现。
  • 为了可重现,这在某些领域是必需的。
  • 可悲的是,对于大多数任务,再现性超出了窗口,因为标准没有为std::uniform_int_distribution 做出类似的保证。因此,在实际环境中,不同的平台会产生不同的结果:(
  • @LightnessRacesinOrbit 目前我发现的唯一参考文献是 wg21 论文 N1398。它对 10,000 和几个随机引擎的特定值有一些基本原理。

标签: c++ c++11 random


【解决方案1】:

来自提案,N1398

在正确考虑任何平台特性[原文如此](例如,奇数大小的整数)的情况下,用户如何确信随机数引擎的实现完全符合指定?毕竟,实现中的小错误可能并不明显;产生的数字可能看起来“随机”。因此,该提议为每个引擎指定了默认构造的引擎对象生成的随机数序列中的第 10000 个数字。

所以它只是一个相对任意的“路点”,被选为确保实现符合此 PRNG 语义的一种方式。

它本身不是语义约束;这是一个验证,实现符合要求。

IMO 标准文本中的注释可能是有序的,因为这是对实施质量进行双重检查的前所未有的方式。 (我不知道任何其他功能的实现 QoI 可以通过标准文本本身中给出的示例数据进行验证。)

归功于Blastfurnace for first arriving at this notion

【讨论】:

  • 可以说,这与规范中说“这样那样的语法应该有这些后置条件”和“这样那样的语法应该发出诊断”的部分没有什么不同
  • @MooingDuck 也许,但它是如此“类似单元测试”;我想不出任何其他涉及具体数据点的例子,至少没有一个不能解释它为什么存在的例子或一个不规范的例子。我没有问题,但这就是我不知道到底发生了什么的原因
【解决方案2】:

所有技术上有用的随机数生成器在设计上都是-随机生成器 (wikipedia)。这意味着他们有一个种子,并根据给定的种子产生 100% 相同的序列。这是在蒙特卡洛模拟等应用中的关键要求,您可能会遇到罕见的问题或错误,如果没有此功能,就不可能开发出任何稳定的复杂蒙特卡洛模拟序列。

所以随机数不会产生随机数。它们产生的数字序列在任何或很长的距离上都具有零相关性。

在您的示例中,默认初始化仅对应于一个特定的此类序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多