问题 提升随机数库,对不同的变量生成器使用相同的随机数生成器


似乎可以使用以下代码从特定的Normal分布生成随机数:

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随机库的设计是否要求用户为每个分布创建一个随机数生成器?显然,我可以编写代码将一系列均匀随机数转换为来自任意分布的序列,但我正在寻找一些简单且已经内置到库中的东西。

在此先感谢您的帮助。


12403
2017-10-28 16:04


起源



答案:


你的假设是正确的。你想要两个 variate_generator 实例使用相同的随机数生成器实例。所以使用引用 mt19937 作为模板参数。

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

显然你必须确保 randgen 以前没有超出范围 nD 和 nC 做。


11
2017-10-28 17:06



这似乎完美无缺。是否将第一个模板参数更改为随机数生成器的内部存储器作为参考?谢谢。 - RandomGuy
是。变量生成器类(相对)简单。原始实例化类具有类型的成员变量 mt19937。正确的,有一个要键入的成员变量 mt19937 &。不会发生其他更改。 - AFoglia
使用对mt19937的引用使variate生成器不可分配;如果需要赋值,则可以使用指针类型。即variate_generator <mt19937 *,normal_distribution <float >> nD(...); - Kyle Simek


答案:


你的假设是正确的。你想要两个 variate_generator 实例使用相同的随机数生成器实例。所以使用引用 mt19937 作为模板参数。

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

显然你必须确保 randgen 以前没有超出范围 nD 和 nC 做。


11
2017-10-28 17:06



这似乎完美无缺。是否将第一个模板参数更改为随机数生成器的内部存储器作为参考?谢谢。 - RandomGuy
是。变量生成器类(相对)简单。原始实例化类具有类型的成员变量 mt19937。正确的,有一个要键入的成员变量 mt19937 &。不会发生其他更改。 - AFoglia
使用对mt19937的引用使variate生成器不可分配;如果需要赋值,则可以使用指针类型。即variate_generator <mt19937 *,normal_distribution <float >> nD(...); - Kyle Simek