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

use*_*778 2 c++ random c++11

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

foo.hpp:

class Foo {
private:
  default_random_engine generator;
  function<float()> sample_pdf1();
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

如果我做:

Foo myFoo;
cout << myFoo.sample_pdf1()() << endl;
cout << myFoo.sample_pdf1()() << endl;
Run Code Online (Sandbox Code Playgroud)

两个样本都是相同的(总是),这不是我想要的.这里有什么问题?生成器是否被绑定(dist,generator)?

还要注意这个例子是简化的,我想要做的是给sample_pdf1()不同的参数,这些参数会产生不同的均值和标准偏差(线性高斯).

R. *_*des 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);
}
Run Code Online (Sandbox Code Playgroud)