【发布时间】:2015-12-02 10:56:40
【问题描述】:
我正在编写蒙特卡罗模拟并实施检查点。我想获得完全相同的结果,无论我是从检查点重新启动模拟还是继续超越它。但是,我遇到了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 确认这一点。
【问题讨论】:
-
这可能只是您的代码中的一个错误吗?你能做一个独立的、可重现的例子吗(例如使用字符串流进行序列化)?
-
@KerrekSB 我认为他没有意识到
normal具有内部状态。 -
确实,我没有。我想知道 Box-Mueller 方法成对生成正常随机数是可以理解的。 (并不是说 Box-Mueller 一定是实现的,但我想原理是一样的。)谢谢,伙计!