我有一个简单的代码示例:
#include <iostream>
#include <random>
using namespace std;
int main() {
minstd_rand0 gen(1);
uniform_real_distribution<double> dist(0.0, 1.0);
for(int i = 0; i < 10; ++i) {
cout << "1 " << dist(gen) << endl;
}
normal_distribution<double> dist2(0.0, 1.0);
minstd_rand0 gen2(1);
for(int i = 0; i < 10; ++i) {
cout << "2 " << dist2(gen2) << endl;
}
return 0;
}
我在gcc和msvc上编译。我在std代码上得到了不同的结果!(
那么为什么GCC和MSVC std::normal_distribution
结果对于相同的种子和生成器是不同的,最重要的是,如何强制它们是相同的?
答案 0 :(得分:7)
与标准定义的PRN生成器不同,该生成器必须为同一种子生成相同的输出,否则标准不会保留对于分布的任务。来自[rand.dist.general] / 3
生成每个指定发行版的算法都是实现定义的。
所以在这种情况下,即使分布必须具有
形式的密度函数实施如何取决于他们。
获得便携式发行版的唯一方法是自己编写一个或使用第三方库。
答案 1 :(得分:6)
这是有问题的,但遗憾的是,标准没有详细说明在构建(多个)随机分布的数字时要使用的算法,并且有几种有效的替代方案,具有不同的好处。
26.6.8.5正态分布[rand.dist.norm] 26.6.8.5.1类模板normal_distribution [rand.dist.norm.normal]
normal_distribution随机数分布产生随机 数字x根据概率密度函数分布
参数μ和也称为此分布的均值和 标准差。
生成正态分布数的最常用算法是 Box-Muller ,但即使使用该算法,也有选项和变体。
标准中甚至明确提到了自由:
26.6.8随机数分布类模板[rand.dist] 。 。
3 用于产生每个指定分布的算法是 实现定义。
goto的选项是boost random
顺便说一下,正如@Hurkyl所指出的那样:似乎这两个实现实际上是相同的:例如,box-muller生成一对值,其中一个返回,一个被缓存。这两种实现的不同之处仅在于返回了哪些值。
此外,随机数引擎已完全指定,并且将在实现之间提供相同的序列,但需要注意,因为不同的分发也可以消耗不同数量的随机数据以产生结果,这会使引擎不同步。