我正在云中进行大型遗传模拟。
通过将虚拟机配置为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();
通过紧密的循环运行随机数生成器会感到有些丑陋,如果生成数非常高,则可能会变慢,我想知道是否有更好的方法可以做到这一点?
答案 0 :(得分:2)
标准库中的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;