c++ - 使用 default_random_engine 作为类成员并且没有类会导致不同的数字(相同的种子)

标签 c++ class random class-members

我想在我的程序中有一个单独的类来生成随机数。我尝试使用 std::default_random_engine 作为类成员,然后生成带有函数的随机 vector 。 当我将结果与没有分类的随机数生成进行比较时,我注意到对于不均匀维度,序列中的一个随机数被跳过。 例如(当然不是随机的):

1,2,3 & 5,6,7 & 9,10,11 (sequence with class)
1,2,3 & 4,5,6 & 7, 8, 9 (sequence without class)

对于偶数维度,两个序列是相同的。所以我试着做了一个示例代码来说明差异。

在这个例子中,我还注意到,在 4-dim 的情况下,一个额外的数字被采样为第一个数字(对于没有类的情况)。如果我使用其他发行版,例如统一,没有这种区别。

有人知道我做错了什么吗?我是否可以将生成器初始化为经常?

感谢任何帮助。

小示例代码:

#include <random>
#include <iostream>

class RandomGenerator{
  public:
    RandomGenerator(int seed):generator_(seed){}
    void generateGaussian(int dim){
      std::normal_distribution<double> distribution(0.,1.);
      for(int i=0; i<dim;++i){
        std::cout<<distribution(generator_)<<std::endl;
      }
    }
  private:
    std::default_random_engine generator_;
};

int main(){
  std::normal_distribution<double> distribution(0.,1.);

  std::cout<<std::endl<<"With Class - 4dim"<<std::endl;
  RandomGenerator random_generator4=RandomGenerator(912134);

  random_generator4.generateGaussian(4);
  std::cout<<"***"<<std::endl;
  random_generator4.generateGaussian(4);
  std::cout<<"***"<<std::endl;
  random_generator4.generateGaussian(4);

  std::cout<<std::endl<<"Without Class"<<std::endl;
  std::default_random_engine generator4(912134);
  for(int i=0; i<15;++i){
    std::cout<<distribution(generator4)<<std::endl;
    if((i+1)%4==0){
        std::cout<<"***"<<std::endl;
    }
  }

  std::default_random_engine generator(912134);
  RandomGenerator random_generator=RandomGenerator(912134);
  std::cout<<"With Class - 3dim "<<std::endl;
  random_generator.generateGaussian(3);
  std::cout<<"***"<<std::endl;
  random_generator.generateGaussian(3);
  std::cout<<"***"<<std::endl;
  random_generator.generateGaussian(3);


  std::cout<<std::endl<<"Without Class"<<std::endl;
  for(int i=0; i<11;++i){
    std::cout<<distribution(generator)<<std::endl;
    if((i+1)%3==0){
        std::cout<<"***"<<std::endl;
    }
  }
  return 0;
}

编辑: 我将此添加到代码中。现在结果完全一样。我将测试统计属性以检查重置后的结果是否仍然是高斯分布的。

if((i+1)%3==0){
    distribution.reset();
    std::cout<<"***"<<std::endl;
}

最佳答案

至少在 C++11 中,分布可能有一个内部状态,就像 PRNGS 一样。 (我观察到这种状态至少用于正态分布;也许 uniform-dist 的行为不同)

如果不准确分析您的代码(我懒惰的 python 编程眼很难阅读),我可以想象这是这些观察结果的来源。

所以当你初始化std::normal_distribution<double> distribution(0.,1.);在你的 main 的第一行,这个对象将在 without class 循环中使用,第二个不会从头开始,因为第一个改变了内部状态(所以播种你的 PRNG 不是够了)。

然而,您的基于类的方法在调用 generateGaussian 时会启动一个新的分发.

关于c++ - 使用 default_random_engine 作为类成员并且没有类会导致不同的数字(相同的种子),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42440455/

相关文章:

c++ - C++ 中 'x % y != 0' 的机制

python - 这些 Python 类方法输出的意义是什么?

c++ - 是否可以在 vb.net 代码中使用 C++ 类?

random - Python-属性错误: 'int' object has no attribute 'randint'

c# - (U)Int64 和 Decimal 的(伪)随机约束值的生成

c++ - 如果默认功能是重新抛出,为什么要有默认异常捕获?

c++ - lual_dofile();不会用 C++ 和 Lua 加载脚本

c++ - 在 Linux 上中止线程 sleep

c++ - 在 IF 中声明派生类以供外部使用

c++ - 获得一个字节的随机性