我正在我的应用程序中调整Mersenne Twister,特别是来自http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html的mt19937ar.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背后的数学就足以弄明白它究竟是什么了。
答案 0 :(得分:4)
这两个是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 - 你只需要保存最近的624个数字{{1 }}。我正在寻找任何现有材料。
Cracking Random Number Generators - Part 3显示了如何使用一些(少至624个)输出数字来推断MT生成器的内部状态。这并不是出乎意料,因为MT的设计强大的统计随机性,而不是安全性作为加密的东西 但是我想在这种情况下解决问题的最简单方法是将自己的代码添加到MT生成器中以保存/恢复其内部状态。