当我看到This Post时,我希望学习如何在C ++中从正态分布中生成数字。它给出了一个很好的例子,但我仍然不确定&
中的boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > var_nor(rng, nd);
是什么意思。如果我在这里没有包含此&
,会产生什么影响?
此外,在阅读Boost's official website上的教程时,我发现在使用boost::random::uniform_int_distribution<> dist(1, 6)
生成分发对象后,他们可以通过调用dist(gen)
(gen)直接生成随机数字。这里是随机引擎),没有调用“variate_generator”对象。当然,这是为了生成统一的随机数,但我很好奇我是否可以使用正态分布做同样的事情,作为调用“variate_generator”的另一种方法?
答案 0 :(得分:4)
生成具有特定分布的随机数的一种方法是,例如,从区间[0,1]生成均匀分布的随机数,然后对这些数字应用一些数学,以将它们整形为所需的分布。所以你有两个对象:一个来自[0,1)的随机数生成器和一个分布对象 采用均匀分布的随机数,并在期望的(例如正常的)分布中吐出随机数。
代码中的var_nor
对象将生成器rnd
与正态分布nd
耦合在一起。您必须通过引用传递您的生成器,这是模板参数中的&
。这非常重要,因为随机数生成器具有内部状态,从中可以计算下一个(伪)随机数。如果您不通过引用传递生成器,您将创建它的副本,这可能会导致代码,它始终创建相同的随机数。请参阅this blog post作为示例。
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;
}
你会看到它只输出NaN
s(我用Boost 1.46测试过它)。原因是Mersenne扭转器返回均匀分布的整数随机数。但是,大多数(可能甚至是所有)连续分布都需要来自[0,1]范围的浮点随机数。 Boost文档中给出的示例有效,因为uniform_int_distribution
是离散分布,因此可以处理整数RNG。
注意:我没有尝试使用较新版本的Boost代码。当然,如果离散RNG与连续分布一起使用,编译器会抛出错误会很好。