2

当我看到这篇文章时,我希望学习如何在 C++ 中从正态分布生成数字。它给出了一个很好的例子,但我仍然不确定&in是什么boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd);意思。如果我不在&这里包含它会产生什么影响?

另外,在阅读Boost官网的教程时,我发现用 生成分布对象后boost::random::uniform_int_distribution<> dist(1, 6),他们可以通过调用dist(gen)(这里的gen是随机引擎)直接用它生成随机数,而无需调用“variate_generator”对象。当然,这是为了生成统一的随机数,但我很好奇我是否可以对正态分布做同样的事情,作为调用“variate_generator”的另一种方法?

4

1 回答 1

4

简短的背景信息

例如,生成具有特定分布的随机数的一种方法是从区间 [0, 1) 生成均匀分布的随机数,然后对这些数字应用一些数学运算以将它们塑造成所需的分布。所以你有两个对象:一个来自 [0, 1) 的随机数生成器和一个分布对象,它采用均匀分布的随机数并在所需(例如正态)分布中吐出随机数。

为什么通过引用传递生成器

代码中的var_nor对象将生成器rnd与正态分布耦合nd。您必须通过引用传递您的生成器,这是&模板参数中的。这真的很重要,因为随机数生成器有一个内部状态,它可以从中计算下一个(伪)随机数。如果您不通过引用传递生成器,您将创建它的副本,这可能会导致代码始终创建相同的随机数。请参阅此博客文章作为示例。

为什么variate_generator是必要的

现在到了部分,为什么不直接使用生成器的分布。如果您尝试以下代码

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>
#include <iostream>

int main()
{
    boost::mt19937 generator;    
    boost::normal_distribution<> distribution(0.0, 1.0);

    // WARNING: THIS DOES NOT WORK AS MIGHT BE EXPECTED!!
    for (int i = 0; i < 100; ++i)
        std::cout << distribution(generator) << std::endl;
    return 0;
}

你会看到,它只输出NaNs(我已经用 Boost 1.46 测试过)。原因是梅森扭曲器返回一个均匀分布的整数随机数。但是,大多数(甚至可能是所有)连续分布都需要[0, 1) 范围内的浮点随机数。Boost 文档中给出的示例之所以有效,是因为uniform_int_distribution它是一个离散分布,因此可以处理整数 RNG。

注意:我还没有尝试过使用更新版本的 Boost 的代码。当然,如果将离散 RNG 与连续分布一起使用,编译器会抛出错误会很好。

于 2012-08-11T16:14:40.580 回答