我试图找到一种实现统一(0,1)分布的有效方法。由于我必须生成大量样本,所以选择mt19937作为引擎。我正在使用boost库中的版本。我的问题是:使用引擎本身的输出与使用uniform_real_distribution之间的区别是什么?
选项#1
std::random_device rd;
boost::mt19937 gen(rd());
boost::random::uniform_real_distribution<double> urand(0, 1);
for ( int i = 0; i < 1E8; i++ ) {
u = urand(gen);
}
选项#2
std::random_device rd;
boost::mt19937 gen(rd());
for ( int i = 0; i < 1E8; i++ ) {
u = (double) gen()/gen.max();
}
从我的测试来看,在运行时方面,选项#2比选项#1好得多。我有什么理由选择#2选项#1?
答案 0 :(得分:1)
我不知道urand()
的基本实现,但是使用除法的结果可能会产生低阶位的偏差作为量化效应。如果gen.max()
不大,那么&#34;低阶位&#34;可能是结果的很多或大部分。
性能差异可能来自产生适当分布的随机数。如果double
对您的需求过于精确,那么使用float
可能会让它更有效地运行。
答案 1 :(得分:0)
我的问题是:使用引擎本身的输出与使用uniform_real_distribution之间的区别是什么?
在您的第一个选项中,urand()
的范围为[0,1)
,而您的第二个选项的范围为[0,1]
(如果boost::mt19937::min() == 0
,通常会保留)。