【问题标题】:Random generators with multiple (uncorrelated?) distributions in c++c++ 中具有多个(不相关?)分布的随机生成器
【发布时间】:2018-06-14 02:04:35
【问题描述】:

已阅读以下问题:

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 个值(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&lt;_Ty,_Wx,_Nx,_Mx,_Rx,_Px,_Ux,_Sx,_Bx,_Tx,_Cx,_Lx&gt;::operator()(void)

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

【问题讨论】:

  • 您将引擎传递给发行版(从中获取编号),因此引擎当然会被使用并更改其内部状态。
  • 谢谢!它有助于。这是否意味着绘制不同的分布(兰特、正态、二项式……)可能会给后续调用带来偏差? (即,先用兰特画,然后再用二项式画,然后再画兰特可能会导致最后一次画法不太准确)?
  • 关于你的“只要你不多线程”的交叉引用:我过去问过random numbers for multiple threads
  • @Grasshoper 我看不出来。我认为这将是随机数生成器的一个弱点,但我不是随机数专家。
  • @MvG 谢谢!没看过,资料不错。如果我理解得很好,那就意味着我真的不需要关心独立的图纸,只要我不按顺序绘制它们。

标签: c++ math random generator


【解决方案1】:

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

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

k-分布到每 1 ≤ k ≤ 623 的 32 位精度(关于 k-分布的定义,请参见 @ 987654323@)

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

【讨论】:

猜你喜欢
  • 2013-02-08
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 2012-05-21
相关资源
最近更新 更多