C++如何产生完全由种子决定的随机序列,与编译器或操作系统无关

Bru*_*man 0 c++ random c++14

考虑以下 C++ 程序,它根据用户输入的种子值生成 10 个随机数序列:

#include <iostream>
#include <random>

int main()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_int_distribution<int> dist(0, 10000);

    int seed;
    std::cout << "Enter seed: ";
    std::cin >> seed;
    mt.seed(seed);

    for (int i=0; i<10; ++i) {
        std::cout << dist(mt) << std::endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我在 MacBook 上运行这个程序并输入种子值 12345 时,它会产生以下随机数序列:

$ bin/demo
Enter seed: 12345
4578
2177
3492
4094
4478
546
7709
3441
7483
6798
Run Code Online (Sandbox Code Playgroud)

如果我再次运行程序并再次输入相同的种子值 12345,那么正如预期的那样,我会得到相同的随机数序列:

$ bin/demo
Enter seed: 12345
4578
2177
3492
4094
4478
546
7709
3441
7483
6798
Run Code Online (Sandbox Code Playgroud)

当我第三次运行程序并输入不同的种子值 11111 时,正如预期的那样,我得到了不同的随机数序列:

Enter seed: 11111
8996
3705
2111
8694
2740
5823
5557
5935
3417
9226
Run Code Online (Sandbox Code Playgroud)

到目前为止,一切都很好:一切都符合预期。

现在我在不同的操作系统上编译完全相同的程序,即在 AWS 中运行的 Ubunty 18.04。

现在,当我像以前一样输入确切的种子值 (12345) 时,我得到的随机数序列与 MacBook 上的不同:

$ bin/demo
Enter seed: 12345
9297
8902
3164
1307
1839
397
2045
8265
5677
5321
Run Code Online (Sandbox Code Playgroud)

我的问题是:我怎样才能编写一个可移植的 C++ 程序,它对于固定的给定种子值总是产生相同的随机数序列,跨编译器和操作系统。

我需要这个来使蒙特卡罗模拟在不同的编译器和操作系统之间可重现(通过设置种子值)。

以防万一:我碰巧正在使用 Clang C++14 编译器(但我希望其他编译器生成相同的随机数序列)。

Pet*_* O. 5

不同之处在于在uniform_int_distributionC++标准库的不同实现中实现方式不同。请注意,决定使用哪种算法的不是“编译器”或“操作系统”。事实上,C++ 分发类,例如uniform_int_distribution没有标准实现。另请参阅此问题

另一方面,诸如此类的随机引擎mt19937确实有保证的实现;它们将为所有兼容的 C++ 库实现中的相同种子返回相同的随机数。您可以通过替换看到自己dist(mt)mt()你在你的问题给出代码。另请参阅此问题