【问题标题】:Bug in std::random when generating normal_distribution? [duplicate]生成 normal_distribution 时 std::random 中的错误? [复制]
【发布时间】:2019-01-12 02:45:51
【问题描述】:

这是我的代码。它假设生成normal_distribution

#include <iostream>
#include <random>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>


int main(int argc, const char *argv[])
{

    // Initialize seed .
    std::mt19937 gena;
    boost::random::mt19937 genb;
    gena.seed( 10 );
    genb.seed( 10 );

    std::normal_distribution<> norma;
    boost::random::normal_distribution<> normb;

    std::cout << "STD BOOST" << std::endl;
    for (size_t i = 0; i < 20; i++) 
        std::cout << norma(gena) << ' ' << normb(genb) << std::endl;

    return 0;
}

我在 arch-linux 上使用 gcc-8.1 编译它,得到以下结果:

STD BOOST -0.0512656 1.16196 -1.90693 -0.742973 1.23919 -1.10165 -0.212754 1.03149 -0.376303 0.597194 0.0660327 -0.12573 -1.01706 1.10728 0.907624 -0.370934 -0.682124 -0.404068 -0.461218 -0.46376 0.965666 -0.607265 0.560664 -1.44186 0.749932 0.449968 -0.31456 -0.268649 0.366249 0.986499 0.608089 -0.500526 -1.08684 -0.0215645 0.120559 -0.805144 1.40203 0.390409 -0.434259 0.0991071

我在 Mac 机器上使用相同的代码(Apple LLVM version 7.0.2 (clang-700.1.81));我得到以下信息:

STD BOOST -1.90693 1.16196 -0.0512656 -0.742973 -0.212754 -1.10165 1.23919 1.03149 0.0660327 0.597194 -0.376303 -0.12573 0.907624 1.10728 -1.01706 -0.370934 -0.461218 -0.404068 -0.682124 -0.46376 0.560664 -0.607265 0.965666 -1.44186 -0.31456 0.449968 0.749932 -0.268649 0.608089 0.986499 0.366249 -0.500526 0.120559 -0.0215645 -1.08684 -0.805144 -0.434259 0.390409 1.40203 0.0991071

注意使用std::random 的第一列是不同的;但如果你仔细观察,第一列有许多共同的元素,但似乎被打乱了。

在我们更换旧的正态分布生成器以支持std::random 之后,我担心 Travis 的一项测试失败(这意味着 Ububtu-14.04 和 xcode-9.2 将显示相同的结果)。

这是一个错误吗?或者我做错了什么? BOOST 运行正常。

【问题讨论】:

  • IIRC, std::*_distribution 依赖于实现,但随机引擎本身应该产生相同的结果。
  • @HolyBlackCat 确实如此。 rng 正在产生相同的序列。事实上,uniform_distribution 也在产生相同的序列。
  • 进行测试时,您应该存入一个您知道每次都会产生相同结果的 RNG。否则,您将获得测试失败。

标签: c++ c++11 random normal-distribution


【解决方案1】:

当您使用不同的编译器(甚至是不同版本的编译器)时,正态分布中的伪随机数不一定因为您使用了相同的种子而必须相同。我不会依赖序列是否相同,除非我使用相同的编译器、编译器版本和可能的优化设置 - 如果您有理由关心,请查看编译器实现文档。

boost 更加一致也就不足为奇了,因为尽管编译器存在差异,但您可能使用的是相同的实现。

【讨论】:

  • generators 产生的具有相同种子的序列在所有实现中都必须相同。即使生成器产生相同的输出序列,通过将生成器的输出馈送到分布所产生的序列也不需要相同。
  • @PeteBecker:确实如此——也许我的错字“在分发中”而不是“分发”使我的意思不太清楚(现在已修复)。我还提供了指向重复 Q 的链接,其中答案强调了这种区别(尽管当 πάντα ῥεῖ 将其作为重复关闭时,有人删除了我对重复的评论)。
  • 措辞非常混乱。 “分布中的伪随机数”......我认为它是指编译器分布。听起来随机数生成器可以为不同的种子提供不同的序列。
  • @Galik:哦:-/。那么我将用“正常”来限定分布。干杯
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多