跨平台一致的伪随机数
Posted
技术标签:
【中文标题】跨平台一致的伪随机数【英文标题】:Consistent pseudo-random numbers across platforms 【发布时间】:2010-10-29 16:07:14 【问题描述】:我正在寻找一种生成伪随机数序列的方法,该方法将在任何平台上为给定种子产生相同的序列结果。我假设 rand()
/ srand()
不会保持一致(我很容易对这个假设出错)。
【问题讨论】:
查看我对 C++11 随机生成器的问答。 C++11 mt19937 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:***.com/questions/34903356/… 如果您选择使用线性同余生成器,this wikipedia page 很有用。特别是,您可以使用 ISO/IEC 9899 中建议的rand
的 C 实现。在我的测试中,当 unsigned long
使用 32(最小值)或 64 位时,它给出了相同的结果。
【参考方案1】:
Mersenne Twister (from Boost.Random) 之类的东西是确定性的。
【讨论】:
如果你不想使用Boost,你可以使用Mersenne Twister的原始实现,它是用纯C编写的。近年来,MT组增加了一些额外的端口,可以使使用 SIMD、OpenCL 和 CUDA。 查看我对 C++11 随机生成器的问答。 C++11 mt19937 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:***.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 在所有平台上提供一致的结果,但标准发行版没有,所以我创建了自己的发行版:***.com/questions/34903356/…【参考方案4】:为此,我一直在开发simplerandom
库。它应该是跨平台的,我的目标也是针对多种语言。目前它支持 C 和Python(两种语言生成相同的数字)。我计划很快在 C++ 中实现相同的生成器,遵循 Boost 和 C++11 随机 API。
【讨论】:
【参考方案5】:快速搜索到的reference 说:
使用相同种子的两个不同初始化,指示伪随机生成器在两种情况下为后续调用 rand 生成相同的连续结果。
但问题仍然存在。我假设上述规范仅适用于同一流程中的 RNG。它很可能没有指定任何关于跨平台或跨编译器的东西。您最好的选择可能是找到一个可用于所有所需平台的库。那么你应该相当安全,如果用相同的值作为种子,它们会返回相同的数字序列。
【讨论】:
我相信这是指rand()
的任何特定实现的行为,并且不提供任何跨编译器或跨平台保证。此外,使用内置 PRNG,您会冒各种不想要的属性的风险。使用已知适合您需求的 PRNG 库。以上是关于跨平台一致的伪随机数的主要内容,如果未能解决你的问题,请参考以下文章