【问题标题】:Can I get the current seed from a Mersenne Twister?我可以从 Mersenne Twister 获得当前种子吗?
【发布时间】:2014-01-11 05:12:18
【问题描述】:

我正在我的应用程序中调整 Mersenne Twister,特别是来自 http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.htmlmt19937ar.c - 代码反映在 https://gist.github.com/mstum/8367363

这在游戏中用作确定性 RNG,为了使保存游戏按预期工作,我需要从 MT 中取出当前种子(而不是初始种子),以便我可以继续。

例如,假设我用12345 的种子初始化它并调用genrand_int31 5 次。这产生了序列1996335345, 1911592690, 679411342, 280691776, 394962642

现在,假设我在第三个数字 (679411342) 之后保存了游戏,然后重新加载并获得两个随机数字。我希望这些数字成为序列的下两个数字 (280691776, 394962642),为此我需要知道第三次迭代后的种子。

作为一种解决方法,我有初始种子和我调用 RNG 的次数,所以现在加载游戏会用初始种子启动 MT 并“重播”genrand_int31,但有数百或数千次次 - 这有点愚蠢:)

我尝试简单地使用mt[N] 数组的第一个元素,但这确实行不通。不幸的是,我不太了解 Mersenne Twister 背后的数学原理,无法弄清楚它的实际运行情况。

【问题讨论】:

    标签: c++ c random


    【解决方案1】:

    这两个是MT生成器的状态,你可以保存这些恢复回来:

    static unsigned long mt[N]; /* the array for the state vector  */
    static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */
    

    也许你需要修改C中的原始源代码。

    另外我不相信存在任何这样的种子可以等同于 MT 的任意状态:种子本身包含 64 位,最多可达 2 ^64个可能的值,远远少于MT可能拥有的状态(其周期为2^19937-1)

    编辑:

    作为一种解决方法,我有初始种子和调用 RNG 的次数,因此现在加载游戏会使用初始种子启动 MT,并“重播”genrand_int31 数百或数千次 -这有点愚蠢:)

    这还不算太愚蠢。 :) 让我告诉你,在 MT 的数学背后,你可以恢复它的连续输出周期的内部状态,确切的数字是 624——你只需要从genrand_int32 保存最近的 624 个数字.我正在寻找这方面的任何现有材料。

    再次编辑:

    Cracking Random Number Generators - Part 3 展示了如何通过一些(少至 624)的输出数来推断 MT 生成器的内部状态。这并不出人意料,因为 MT 是为强大的统计随机性而设计的,而不是加密的安全性。
    但是我认为在这种情况下,解决您的问题的最简单方法是将您自己的代码添加到 MT 生成器中以保存/恢复其内部状态。

    【讨论】:

    • 您可以将 genrand_int32 的返回值传递给向量,但需要移动“回火”
    • 谢谢,这也是一个很好的解决方法,因为这意味着 625 * 4 字节的存储空间,完全可以(2500 字节存储空间)
    • 那个链接太棒了,很好的解释,谢谢!就我而言,保存整个数组和 mti 是最简单的。
    • 如果保存整个状态不切实际,您还可以在每 n 代之后生成并保留一个新种子。这样你就可以控制你必须做的“重播”的数量。
    猜你喜欢
    • 2010-12-19
    • 2014-02-22
    • 2017-06-10
    • 2017-08-20
    • 2016-02-21
    • 2012-01-13
    • 2016-01-06
    • 2014-04-17
    • 2011-09-28
    相关资源
    最近更新 更多