Boost随机数库:为不同的变量生成器使用相同的随机数生成器。

11

似乎可以使用以下代码从特定正态分布中产生随机数:

float mean = 0, variance = 1;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise(mean, variance);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise);

float random = nD();

这个可以正常工作,但我想从几个分布中抽取数字,也就是说:

float mean1 = 0, variance1 = 1, mean2 = 10, variance2 = 0.25;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise1(mean1, variance1);
boost::normal_distribution<float> noise2(mean2, variance2);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise1);
variate_generator<mt19937, normal_distribution<float> > nC(randgen, noise2);

float random1 = nD();
float random2 = nC();
然而,问题似乎在于nD()和nC()生成了相似的数字序列。我猜想这是因为variate_generator的构造函数似乎复制了randgen,而不是显式地使用它。因此,同样的伪随机序列正在生成并通过不同的转换(由于分布的不同参数)简单地传递。

有没有人知道在Boost中是否有一种方法可以创建单个随机数生成器并将其用于多个分布?或者说,Boost随机库的设计意图是让用户为每个分布创建一个随机数生成器吗?显然,我可以编写代码将一系列均匀分布的随机数转换为任意分布的序列,但我正在寻找一些简单且已经内置于库中的内容。

提前感谢您的帮助。

1个回答

11

您的假设是正确的。您想让两个variate_generator实例使用同一个随机数生成器实例。因此,将mt19937的引用作为模板参数。

variate_generator<mt19937 &, normal_distribution<float> > nD(randgen, noise1);
variate_generator<mt19937 &, normal_distribution<float> > nC(randgen, noise2);

显然,您必须确保在nDnC之前,randgen不会超出其范围。


那似乎完美地工作了。将第一个模板参数设置为引用是否只是改变了随机数生成器的内部存储方式?谢谢。 - RandomGuy
1
是的。变量生成器类(相对而言)很简单。原始实例化类具有类型为mt19937的成员变量。正确的类应该有一个类型为mt19937 &的成员变量。没有发生其他更改。 - AFoglia
1
使用对 mt19937 的引用会使变量生成器不可赋值;如果需要赋值,可以使用指针类型。即 variate_generator<mt19937*,normal_distribution<float>> nD(...)。 - Kyle Simek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接