我应该在我的C++标准随机分布上调用reset()来清除隐藏状态吗?

Tyl*_*ter 10 c++ random standard-library c++11

我想用C++ 11标准库中的随机数分布包含简单的函数,这些函数将分布的参数和生成器实例作为参数.例如:

double normal(double mean, double sd, std::mt19937_64& generator)
{
    static std::normal_distribution<double> dist;
    return dist(generator, std::normal_distribution<double>::param_type(mean, sd));
}
Run Code Online (Sandbox Code Playgroud)

我想避免分发对象中的任何隐藏状态,以便每个对此包装函数的调用仅取决于给定的参数.(可能每次调用此函数都可以使用不同的生成器实例.)理想情况下,我会使分发实例static const确保这一点; 但是,分布operator()不是const函数,所以这是不可能的.

我的问题是:为确保分发中没有隐藏状态,是否1)必要且2)足以reset()每次呼叫分配?例如:

double normal(double mean, double sd, std::mt19937_64& generator)
{
    static std::normal_distribution<double> dist;
    dist.reset();
    return dist(generator, std::normal_distribution<double>::param_type(mean, sd));
}
Run Code Online (Sandbox Code Playgroud)

(总的来说,我reset()对随机分布函数的目的感到困惑......我理解为什么生成器有时需要重置/重新设置,但为什么分配对象需要重置?)

How*_*ant 8

为确保分布中没有隐藏状态,是否必要

是.

2)每次足以在分配上调用reset()吗?

是.

你可能不想这样做.至少不是每次通话都没有.这std::normal_distribution是允许分发维持状态的海报孩子.例如,一个流行的实现将使用Box-Muller转换一次计算两个随机数,但是只返回其中一个,在下次调用时保存另一个.reset()在下一次调用之前调用将导致分发丢弃这个已经有效的结果,并将算法的效率降低一半.

  • @TylerStreeter:对于 libc++ 实现来说确实如此。表 118 指定了使用 urng 调用分布的行为,仅指定了“使用 **相同​​* 对象`g` 的连续调用”的行为。未指定具有不同 urng 的连续调用。 (2认同)