我有一个带有随机引擎生成器对象和函数的类,它返回表示不同分布但使用相同生成器的函数。
foo.hpp:
class Foo {
private:
default_random_engine generator;
function<float()> sample_pdf1();
Foo.cpp中:
function<float()> Foo::sample_pdf1() {
float mean = 3.0f;
float stddev = 1.0f;
normal_distribution<float> dist(mean,stddev);
return bind(dist,generator);
}
如果我这样做:
Foo myFoo;
cout << myFoo.sample_pdf1()() << endl;
cout << myFoo.sample_pdf1()() << endl;
两个样本都是相同的(总是),这不是我想要的。这里有什么问题?生成器是否在bind(dist,generator)中被复制?
另请注意,此示例已简化,我想要做的是给sample_pdf1()不同的参数,这些参数会产生不同的均值和标准偏差(线性高斯)。
答案 0 :(得分:6)
问题是代码按值绑定生成器。函数返回的每个采样器都有自己的生成器副本。所有这些副本都有相同的种子。生成器是确定性的:如果使用相同的种子初始化生成器,则会得到相同的数字序列。
您可以通过引用绑定生成器:bind(dist, std::ref(generator));
。这样两个采样器将使用相同的生成器而不是每个使用自己的副本。
或者,您可以为每个采样器播种不同的生成器,如下所示。
function<float()> Foo::sample_pdf1() {
// a source of entropy to obtain seeds
static std::random_device entropy;
float mean = 3.0f;
float stddev = 1.0f;
normal_distribution<float> dist(mean,stddev);
// seed a new generator for this sampler
auto generator = default_random_engine(entropy());
return bind(dist,generator);
}