【问题标题】:Consistent pseudo-random numbers across platforms跨平台一致的伪随机数
【发布时间】:2010-10-29 16:07:14
【问题描述】:

我正在寻找一种生成伪随机数序列的方法,该方法将在任何平台上为给定种子产生相同的序列结果。我假设 rand() / srand() 不会保持一致(我很容易对这个假设出错)。

【问题讨论】:

  • 查看我对 C++11 随机生成器的问答。 C++11 mt19937 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:stackoverflow.com/questions/34903356/…
  • 如果您选择使用线性同余生成器,this wikipedia page 很有用。特别是,您可以使用 ISO/IEC 9899 中建议的 rand 的 C 实现。在我的测试中,当 unsigned long 使用 32(最小值)或 64 位时,它给出了相同的结果。

标签: c++ c random


【解决方案1】:

Mersenne Twister (from Boost.Random) 之类的东西是确定性的。

【讨论】:

  • 如果你不想使用Boost,你可以使用Mersenne Twister的原始实现,它是用纯C编写的。近年来,MT组增加了一些额外的端口,可以使使用 SIMD、OpenCL 和 CUDA。
  • 查看我对 C++11 随机生成器的问答。 C++11 mt19937 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:stackoverflow.com/questions/34903356/…
【解决方案2】:

Knuth 有released into the public domain C (and FORTRAN) source code 用于计算机编程的艺术第 3.6 节中描述的伪随机数生成器。

【讨论】:

    【解决方案3】:

    我意识到这是一个旧线程,但现在使用 C++11 有一大堆 new options available。这是页面中的一个提炼示例,默认使用Mersenne Twister 引擎和Normal 分发:

    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <map>
    #include <random>
    
    int main()
    {
        std::random_device rd;
    
        //
        // Engines 
        //
        std::mt19937 e2(rd());
        //std::knuth_b e2(rd());
        //std::default_random_engine e2(rd()) ;
    
        //
        // Distribtuions
        //
        std::normal_distribution<> dist(2, 2);
        //std::student_t_distribution<> dist(5);
        //std::poisson_distribution<> dist(2);
        //std::extreme_value_distribution<> dist(0,2);
    
        std::map<int, int> hist;
        for (int n = 0; n < 10000; ++n) {
            ++hist[std::round(dist(e2))];
        }
    
        for (auto p : hist) {
            std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                      << p.first << ' ' << std::string(p.second/200, '*') << '\n';
        }
    }
    

    【讨论】:

    • C++11 标准指定的分布不需要在给定相同种子的情况下产生可重现的结果,即使使用相同的代码也是如此。更不用说使用不同的库了,比如 libc++ vs libstdc++。
    • 查看我对 C++11 随机生成器的问答。 C++11 mt19937 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:stackoverflow.com/questions/34903356/…
    【解决方案4】:

    为此,我一直在开发simplerandom 库。它应该是跨平台的,我的目标也是针对多种语言。目前它支持 C 和Python(两种语言生成相同的数字)。我计划很快在 C++ 中实现相同的生成器,遵循 Boost 和 C++11 随机 API。

    【讨论】:

      【解决方案5】:

      快速搜索到的reference 说:

      使用相同种子的两个不同初始化,指示伪随机生成器在两种情况下为后续调用 rand 生成相同的连续结果。

      但问题仍然存在。我假设上述规范仅适用于同一流程中的 RNG。它很可能没有指定任何关于跨平台或跨编译器的东西。您最好的选择可能是找到一个可用于所有所需平台的库。那么你应该相当安全,如果用相同的值作为种子,它们会返回相同的数字序列。

      【讨论】:

      • 我相信这是指rand() 的任何特定实现的行为,并且不提供任何跨编译器或跨平台保证。此外,使用内置 PRNG,您会冒各种不想要的属性的风险。使用已知适合您需求的 PRNG 库。
      猜你喜欢
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-26
      • 1970-01-01
      • 2021-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多