我正在编写蒙特卡罗模拟并实施检查点。我想获得完全相同的结果,无论我是否从检查点重新启动模拟或继续超出它。但是,我遇到了std::normal_distribution
的一些奇怪的行为:
我使用std::mt19937 rng;
作为RNG并将其播种到固定数字。我通过std::uniform_real_distribution uniform;
和std::normal_distribution normal;
绘制了一定数量的随机数。然后,我将rng的状态写为ofstream os
:
os << rng << endl;
os << <some other stuff>...
之后,我又画了几个数字:
os << uniform(rng) << endl;
os << uniform(rng) << endl;
os << uniform(rng) << endl;
os << normal(rng) << endl;
os << normal(rng) << endl;
os << normal(rng) << endl;
os << uniform(rng) << endl;
os << uniform(rng) << endl;
os << uniform(rng) << endl;
我得到以下输出:
0.727133
0.215537
0.516879
-2.12532
0.314652
1.78136
0.511111
0.83119
0.637067
但是,如果我从检查点重新启动,即从ifstream is
初始化生成器:
is >> rng;
is >> <some other stuff>...
并绘制相同的9个随机数(3个制服,3个正常,3个制服),我得到:
0.727133
0.215537
0.516879
0.314652
1.78136
1.28201
0.637067
0.298175
0.802607
你看,统一数字是相同的,直到绘制了正常数字,之后rng的状态不同。单步执行gdb
即可确认。
答案 0 :(得分:3)
查看两个输出中0.637067
的位置。您会注意到正常分布在恢复时必须从rng中拉出比未恢复时更多的数字。那是因为当你检查点时它有熵。
您必须保存或重置normal
的状态。我建议在normal
上调用reset作为检查点流程的一部分。