【问题标题】:C++ std::mt19937 and rng state save/load & portabilityC++ std::mt19937 和 rng 状态保存/加载和可移植性
【发布时间】:2015-02-27 21:22:49
【问题描述】:

我希望能够保存和加载 RNG 的状态,以便我可以从给定点(应用程序保存/快照)再现相同的随机值。

我看到有一个运算符 > 重载,它似乎以数字序列的形式保存到字符串中。

  • 这是最好/唯一的保存方式吗?我不介意只有固定大小的二进制状态值而不是这个空格分隔的字符串,然后我需要为我的文件格式添加前缀或分隔符。
  • 这是便携的吗?例如我可以在不同的编译器版本之间传输,甚至在 MSVC 和 GCC 之间传输,以在给定相同配置的分布的情况下生成相同的数据集(在浮点的情况下误差很小,对于整数数学精确)?

【问题讨论】:

    标签: c++ serialization random


    【解决方案1】:

    在上一个答案之上:

    • 通过 op> 读回时才会保存正确的 RNG 状态。更改语言环境会导致问题

    • default_random_engine 的选择由实现定义。它是一个 typedef,但允许在不同平台上设置为不同的真实引擎(第 26.5.5 节)。因此,使用 op> 来保存/恢复状态几乎禁止使用默认引擎

    • 虽然生成器的指定非常严格,但我不认为平台之间的分布必须相同。在此处保存状态可能对您的可重复性没有多大帮助

    我建议将这份文件放在手边,以防万一http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf

    【讨论】:

    • 好的,似乎分发算法是实现定义的,所以我必须自己获取...所以它们的通用语言环境是完全固定的,可以轻松应用于流(例如 std::stringstream )?也许我必须回到 Boost.Random 虽然我认为它也有这个烦人的流的东西。
    • @FireLancer 是的,您可以在 I/O 操作之前灌输语言环境,请参阅 cplusplus.com/reference/ios/ios/imbue
    【解决方案2】:

    是的,operator<<operator>> 是导入或导出随机数生成器状态的唯一方法。如果您愿意,可以轻松地将文本表示转换为二进制表示。

    反序列化和序列化mt19937 状态应该在实现之间是可移植的。通过流操作符读取和写入引擎状态的结果在标准中得到了很好的定义,只要您确保流具有相同的语言环境。

    operator<<operator>> 的要求参见第 26.5.1.5 节,mersenne_twister_engine文本表示随后是第 26.5.3.2 节,mt19937 是一个很好的定义typedef 的。

    【讨论】:

      猜你喜欢
      • 2019-11-20
      • 1970-01-01
      • 2011-02-15
      • 2021-11-24
      • 2011-10-03
      • 2014-08-21
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      相关资源
      最近更新 更多