阅读了以下问题:
using one random engine for multi distributions in c++11
Uncorrelated parallel random seeds with C++ 2011?
std::default_random_engine generate values between 0.0 and 1.0
how to generate uncorrelated random sequences using c++
Using same random number generator across multiple functions
在我对c ++中多个(不同)发行版的随机生成器的概念性理解中,经历过一些技巧已经引起了人们的怀疑。特别是:
例如,假设我使用以下内容:
class Zsim {
private:
std::default_random_engine engine;
}
并在构造函数中初始化它:
Zsim::Zsim(...)
{
std::random_device rd;
std::default_random_engine generator(rd());
engine = generator;
}
并使用它在不同的分布(二项和均匀)中绘制n个值(可能很大),让我们说:
std::binomial_distribution<int> B_distribution(9, 0.5);
int number = B_distribution(engine);
std::uniform_real_distribution<double> R_distribution(0, 15);
position.x = R_distribution(engine);
position.y = R_distribution(engine);
这被认为是好的吗?
一些人指出使用std::random_device
很好,而其他人建议它可以抛出多种原因,应该避免或尝试/捕获(参见:Using same random number generator across multiple functions)。
int Zscim::get_randomB() const
{
std::binomial_distribution<int> B_distribution(9, 0.5);
int number = B_distribution(engine);
}
编译器抛出一个错误:expression having type 'const std::tr1::default_random_engine' would lose some const-volatile qualifiers in order to call 'unsigned long std::tr1::mersenne_twister<_Ty,_Wx,_Nx,_Mx,_Rx,_Px,_Ux,_Sx,_Bx,_Tx,_Cx,_Lx>::operator()(void)
建议在调用分发时以某种方式更改生成器“引擎”。是什么造成的?
如果您阅读有关UniformRandomBitGenerator的信息,您会发现随机生成器将生成随机位,理想情况下它们彼此非常独立,只要有问题的PRNG可以实现这一点。所以基本上每次调用engine()
都会生成一个几乎不相关的整数。分发的任务是对此进行适当的调用。对于分发本身的每32次调用,单个位分配可能会对32位引擎进行单次调用,从而在调用之间缓存未使用的熵。相反,双精度数生成器可能使用来自两个32位引擎结果的熵来确定双精度的所有53个尾数位。引擎不关心哪个分布消耗其随机位,因此在不同分布中使用相同的引擎不是问题。
如果您阅读https://en.wikipedia.org/wiki/Mersenne_Twister,您会发现它是
每1≤k≤623k分布到32位精度(对于k分布的定义,请参阅below)
因此,如果你使用std::mt19937
,我会说你应该安全地在多达623种不同的发行版中使用相同的引擎,无论它们是相同还是不同类型。对于更多的发行版,它取决于它们的使用方式,但在大多数情况下我也不会太担心。