mt19937和uniform_real_distribution

时间:2014-12-09 05:35:34

标签: c++ boost prng mersenne-twister

我试图找到一种实现统一(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?

2 个答案:

答案 0 :(得分:1)

我不知道urand()的基本实现,但是使用除法的结果可能会产生低阶位的偏差作为量化效应。如果gen.max()不大,那么&#34;低阶位&#34;可能是结果的很多或大部分。

性能差异可能来自产生适当分布的随机数。如果double对您的需求过于精确,那么使用float可能会让它更有效地运行。

答案 1 :(得分:0)

  

我的问题是:使用引擎本身的输出与使用uniform_real_distribution之间的区别是什么?

在您的第一个选项中,urand()的范围为[0,1),而您的第二个选项的范围为[0,1](如果boost::mt19937::min() == 0,通常会保留)。