当我可以将RNG传递给分发时,为什么要使用variate_generator? (具体来说是C ++和Boost)

时间:2013-08-15 05:52:28

标签: c++ boost random

我为什么要这样做:

#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次迭代,其中发生随机过程。这意味着我需要非常好的随机数。

1 个答案:

答案 0 :(得分:1)

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

variate_generator就是为了方便起见,因此每次需要新号码时都不需要使用norm_dist(rng)参数调用rng

如果您构建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()初始化生成器,因此这两个实例将以相同的数字播种。因此,两个实例都将使用完全相同的随机数序列。

在科学应用中,优良作法是手动播种随机数发生器(以确保它们用不同的种子初始化)或至少记录/记录使用过的种子。这样,您就可以重现伪随机数序列,从而重现程序的结果。