【问题标题】:Why use variate_generator when I can just pass the RNG to the distribution? (C++ and Boost, specifically)当我可以将 RNG 传递给分发时,为什么要使用 variate_generator? (特别是 C++ 和 Boost)
【发布时间】:2013-08-16 17:11:31
【问题描述】:

我为什么要这样做:

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

【问题讨论】:

    标签: c++ boost random


    【解决方案1】:

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

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

    如果你构造了一个variate_generator&lt;mt19937&amp;, normal_distribution&lt;double&gt; &gt; 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() 初始化生成器,因此这两个实例将使用相同的数字作为种子。因此,两个实例都将使用完全相同的随机数序列。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 2021-06-18
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多