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