在 C++ 中从给定的种子生成相同的随机数序列

jef*_*eon 5 c++ random deterministic mersenne-twister

我正在使用 mt19937 从给定种子生成随机字符串,如下所示:

std::string StringUtils::randstring(size_t length, uint64_t seed) {
    static auto& chrs = "abcdefghijklmnopqrstuvwxyz";

    thread_local static std::mt19937 rg(seed);
    thread_local static std::uniform_int_distribution<std::string::size_type> pick(0, sizeof(chrs) - 2);

    std::string s;
    s.reserve(length);

    while(length--) {
        s += chrs[pick(rg)];
    }

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

我想保证随机数序列(以及生成的随机字符串)在同一架构的不同机器上是相同的,根据这个问题的答案应该是这样的。

但是,当我重建二进制文件(不更改任何依赖项或库)时,同一种子的随机数序列会发生变化(与使用相同种子的先前构建生成的序列相比)。

如何从同一机器架构+映像(x86_64 Linux)上不同二进制文件的给定种子生成有保证的随机数序列?

Pet*_* O. 5

如果您关心可重复的“随机”数字,您应该避免 C++ 发行版,包括uniform_int_distribution,而是依靠您自己的方式将伪随机数转换为mt19937您想要的数字。(例如,我给出了对统一整数执行此操作的方法。请注意,当可重复性很重要时,还需要考虑其他事项。)

C++ 分发类,例如uniform_int_distribution没有标准实现。因此,这些分发类可以在 C++ 标准库的不同实现中以不同的方式实现。请注意,决定使用哪种算法的不是“编译器”、“操作系统”或“体系结构”。另请参阅这个问题

另一方面,诸如此类的随机引擎确实mt19937有一个有保证的实现;它们将为所有兼容的 C++ 库实现(包括不同“体系结构”的库实现)中的相同种子返回相同的伪随机数。例外的是default_random_engine