在 C++11 中保存和加载随机数生成器状态

Pie*_*der 5 c++ c++-standard-library c++11 mt19937

之前(stackoverflow)已经问过这个问题,但(接受的)答案并不令人满意。

以下示例保存并加载状态,但取决于生成的值的数量,它是否起作用:

#include <fstream>
#include <iostream>
#include <random>
#include <cassert>

int main()
{
  const int preN = 4;
  const int middleN = 0;

  // initialize randGen
  std::mt19937 randGen1;
  std::normal_distribution<double> distribution1;


  // print some initial random numbers
  for (int i=0;i<preN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // save state
  std::cout << std::endl << "Saving...\n";
  {
    std::ofstream fout("seed.dat");
    fout << randGen1;
  }

  // maybe advance randGen1
  for (int i=0;i<middleN;++i)
    std::cout << distribution1(randGen1)<<" ";

  // load saved state into randGen2 
  std::cout << std::endl << "Loading...\n";
  std::ifstream fin("seed.dat");
  std::mt19937 randGen2;
  fin >> randGen2;
  std::normal_distribution<double> distribution2;

  // are both randGen equal?
  assert(randGen1 == randGen2);

  // print numbers from both generators
  std::cout << "Generator1\tGenerator2\n";
  std::cout << distribution1(randGen1) << "\t"
            << distribution2(randGen2) << "\n";

  return 0;

}    
Run Code Online (Sandbox Code Playgroud)

使用这些参数,它可以按预期工作。但是,如果我设置preN=3输出如下所示:

0.13453 -0.146382 0.46065 
Saving...

Loading...
Generator1  Generator2
-1.87138    0.163712
Run Code Online (Sandbox Code Playgroud)

为什么断言不适用?现在我设置preN=3middleN=1输出是

0.13453 -0.146382 0.46065 
Saving...
-1.87138 
Loading...
Generator1  Generator2
0.163712    0.163712
Run Code Online (Sandbox Code Playgroud)

如果我设置middleN为大于 1 的任何值,则断言适用。任何人都可以解释发生了什么?我做错了什么或不理解?

在 Linux 上使用 GCC5.4.0 和 CLANG3.8.0 进行测试

Nic*_*las 5

问题不在于您的随机数生成器的状态。问题在于您的发行版状态。是的,发行版也可以有状态。

您可以通过使用 重置正态分布的状态来获得相同的值reset。或者,您也可以使用和保留和重建分布的状态。<<>>