5

我试图找到一种有效的方法来实现统一(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 好得多。有什么理由我应该选择选项 #1 而不是选项 #2?

4

2 回答 2

1

我不知道 的底层实现urand(),但是使用除法的结果可能会在低位中产生偏差作为量化效果。如果gen.max()不是很大,那么“低位”可能是结果的很多或大部分位。

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

于 2014-12-10T18:14:15.080 回答
0

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

在您的第一个选项urand()中有 range [0,1),而您的第二个选项有 range [0,1](如果boost::mt19937::min() == 0,通常成立)。

于 2014-12-09T06:20:37.030 回答