使用相同的生成器<random> c ++ 11 </random>避免使用相同的随机数

时间:2014-04-10 12:01:55

标签: c++ c++11 random

我有一个带有随机引擎生成器对象和函数的类,它返回表示不同分布但使用相同生成器的函数。

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()不同的参数,这些参数会产生不同的均值和标准偏差(线性高斯)。

1 个答案:

答案 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);
}
相关问题