在c ++中具有多个(不相关的?)分布的随机生成器

问题描述 投票:2回答:1

阅读了以下问题:

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)。

  • using one random engine for multi distributions in c++11中,有人建议,当模拟n维的随机或布朗运动时(在MosteM给出的例子中n = 2),每个维度需要一个发生器,否则它们会相互关联,产生人工漂移。虽然我同意这个断言,但鉴于发电机的(大)周期,这个断言的有效性是什么?如果模拟很大(步数多)?我们是否应该每个维度使用一个生成器作为安全性?这似乎与how to generate uncorrelated random sequences using c++的主要答复相矛盾
  • 最后,给定Zsim示例,当您向方法添加const限定符并绘制二项分布时: 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)

建议在调用分发时以某种方式更改生成器“引擎”。是什么造成的?

c++ math random generator
1个回答
2
投票

如果您阅读有关UniformRandomBitGenerator的信息,您会发现随机生成器将生成随机位,理想情况下它们彼此非常独立,只要有问题的PRNG可以实现这一点。所以基本上每次调用engine()都会生成一个几乎不相关的整数。分发的任务是对此进行适当的调用。对于分发本身的每32次调用,单个位分配可能会对32位引擎进行单次调用,从而在调用之间缓存未使用的熵。相反,双精度数生成器可能使用来自两个32位引擎结果的熵来确定双精度的所有53个尾数位。引擎不关心哪个分布消耗其随机位,因此在不同分布中使用相同的引擎不是问题。

如果您阅读https://en.wikipedia.org/wiki/Mersenne_Twister,您会发现它是

每1≤k≤623k分布到32位精度(对于k分布的定义,请参阅below

因此,如果你使用std::mt19937,我会说你应该安全地在多达623种不同的发行版中使用相同的引擎,无论它们是相同还是不同类型。对于更多的发行版,它取决于它们的使用方式,但在大多数情况下我也不会太担心。

© www.soinside.com 2019 - 2024. All rights reserved.