1

为什么我应该这样做:

#include <boost/random.hpp>
#include <ctime>

using namespace boost;

double SampleNormal (double mean, double sigma)
{
    static mt19937 rng(static_cast<unsigned> (std::time(0)));
    normal_distribution<double> norm_dist(mean, sigma);
    variate_generator<mt19937&, normal_distribution<double> >  normal_sampler(rng,         norm_dist);
    return normal_sampler();
}

在我看来,代码:

#include <boost/random.hpp>
#include <ctime>

using namespace boost;

double SampleNormal (double mean, double sigma)
{
    static mt19937 rng(static_cast<unsigned> (std::time(0)));
    normal_distribution<double> norm_dist(mean, sigma);
    return norm_dist(rng);
}

应该也能正常工作。

为什么使用variate_generator?它是否比第二个示例中所做的更多?

一点背景知识:我正在运行 100 个模拟实例,其中涉及发生随机过程的循环的 10^7 次迭代。这意味着我需要非常好的随机数。

4

1 回答 1

1

无需使用variate_generator,两个代码示例都可以。

variate_generator 只是为了方便起见,这样您就不需要在每次需要新号码时都norm_dist(rng)使用参数调用。rng

如果您构造 a ,则每次想要获取新号码时都variate_generator<mt19937&, normal_distribution<double> > normal_distr_rnd_num可以调用。normal_distr_rnd_num()在某些情况下,这可能会使代码更具可读性。

我不确定你想用这个SampleNormal(double mean, double sigma)函数做什么。如果您经常使用相同的值调用该函数,(mean,sigma)那么构造这样的 variate_generator 对象可能值得 - 让我们调用它sample_normal- 然后只需调用sample_normal()而不是您的函数。


对数字质量的评论:数字
的质量主要取决于底层的伪随机数算法,即您选择的生成器。mt19337 的周期为 2^19937-1,应该足以满足 10^7 = 2^24(大约)个数字,并且两个连续数字之间没有“明显”的相关性。然而,这些数字仍然是由单一的确定性算法产生的。您的应用程序可能只是证明这种确定性的测试,但可能性不大。因此,您还可以更改伪随机数生成器,以查看您的应用程序是否使用完全不同的生成伪随机数的方式给出相同的结果。

我更关心生成器的初始化(播种)。如果您运行 100 个实例,则很有可能并行执行此操作。现在,如果您并行运行其中一些实例,则可能会同时启动两个实例。由于您使用 初始化生成器time(),因此这两个实例将使用相同的数字作为种子。因此,两个实例都将使用完全相同的随机数序列。

在科学应用中,手动为随机数生成器播种(以确保它们使用不同的种子进行初始化)或至少记录/记录使用的种子是一种很好的做法。通过这种方式,您可以重现伪随机数序列,从而重现程序的结果。

于 2013-08-16T08:07:30.647 回答