我正在云中运行大型遗传模拟。
通过将虚拟机配置为preemptible,可以大大降低云资源的成本。
为了从先发制人中恢复过来,我在每一代的开始时都保存了种群特工的状态,重新启动时,我加载了状态,并从最后完成的那一代开始继续,而不必进化每次都是从零开始的人口。
这一直很好,但是现在出于测试目的,我希望有可重复的模拟。
我用已知的种子值为我的随机数生成器(当前使用std::mt19937
播种,并且直到我的虚拟机被抢占为止一直有效。
[当我重新加载当前一代时,我需要同时重新加载随机数发生器的状态,以便它也“从中断的地方开始”。
[我发现我可以通过紧密的循环来运行生成器,丢弃生成器生成的所有值,直到进入要从中恢复的迭代为止:
const std::size_t generation = load_state_from_file();
std::mt19937 engine;
engine.seed(constant_seed_value);
// discard the first N generated values
for (std::size_t i = 0; i < generation; ++i)
engine();
通过紧密循环运行随机数生成器会感到有些丑陋,并且如果生成数非常高,则可能会变慢,我想知道是否有更好的方法可以做到这一点?
标准库中的RNG内置支持通过operator<< and operator>>进行序列化和反序列化。
std::mt19937 engine;
engine.seed(constant_seed_value);
// use the engine and then later
output_stream << engine; // save it's internal state to a stream
然后下次使用它时,将数据加载回
std::mt19937 engine;
input_stream_with_the_stored_state >> engine;