在c ++

时间:2018-01-04 10:49:19

标签: c++ math random generator

阅读了以下问题:

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)

建议发电机&#39;引擎&#39;调用分发时会以某种方式更改。造成这种情况的原因是什么?

1 个答案:

答案 0 :(得分:2)

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

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

  

k - 每1≤ k ≤623分配到32位精度(对于 k -distributed的定义,请参阅{ {3}})

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