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

标签 c++ random c++11 standard-library

我想用简单的函数包装来自 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));
}

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

我的问题是:为了确保分布中没有隐藏状态,每次在分布上调用 reset() 是否 1) 必要且 2) 足够?例如:

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));
}

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

最佳答案

To ensure there is no hidden state within the distribution, is it 1) necessary

是的。

and 2) sufficient to call reset() on the distribution each time?

是的。

不过您可能不想这样做。至少不是在每次通话中。 std::normal_distribution 是允许分布保持状态的典范。例如,一个流行的实现将使用 Box-Muller transformation一次计算两个随机数,但只把其中一个还给你,另一个留到下次调用时使用。在下一次调用之前调用 reset() 会导致分发丢弃这个已经有效的结果,并将算法的效率减半。

关于c++ - 我应该在我的 C++ std 随机分布上调用 reset() 来清除隐藏状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14857597/

相关文章:

c++ - RAII与std::function

c++ - 模板类构造函数接受参数时出错

c++ - 最好情况,最坏情况,插入排序算法的随机数据输入?

c++ - 什么是 glibc free/malloc/realloc invalid next size/invalid pointer error 以及如何修复它?

python - 播放.wav文件x秒

multithreading - 如何创建运行抽象类的成员函数的 std::thread?

c++ - 如何随机化这些数字?

vb.net - 如何生成给定范围内的随机数?VB.NET

c++ - 是否有用于 C 字符串的标准 C++ 迭代器?

c++ - 在 C++ 中,我可以声明一个引用以表明不会修改它吗?