Random 制作可定制的前后移动LCG

Random 制作可定制的前后移动LCG,random,procedural-generation,lcg,Random,Procedural Generation,Lcg,我将如何使LCG(伪随机数生成器类型)在两个方向上运行? 我知道向前行驶是(a*x+c)%m,但我怎样才能逆转它呢? 我使用它是为了将种子存储在地图中播放器的位置,并能够通过在LCG中前后传播(如某种随机数字线)来生成种子周围的内容。所有LCG循环。在达到最大循环长度的LCG中,每个值x都有一个唯一的前导和一个唯一的后继(对于没有达到最大循环长度的LCG或具有子循环行为的其他算法,如冯·诺依曼算法,这不一定是真的) 假设我们的LCG有循环长度L。由于行为是循环的,这意味着在L次迭代之后,我们回到

我将如何使LCG(伪随机数生成器类型)在两个方向上运行? 我知道向前行驶是
(a*x+c)%m
,但我怎样才能逆转它呢?
我使用它是为了将种子存储在地图中播放器的位置,并能够通过在LCG中前后传播(如某种随机数字线)来生成种子周围的内容。

所有LCG循环。在达到最大循环长度的LCG中,每个值x都有一个唯一的前导和一个唯一的后继(对于没有达到最大循环长度的LCG或具有子循环行为的其他算法,如冯·诺依曼算法,这不一定是真的)

假设我们的LCG有循环长度L。由于行为是循环的,这意味着在L次迭代之后,我们回到了起始值。通过向后退一步来查找前置值在数学上等同于向前走(L-1)步

最大的问题是,这是否可以转化为一个步骤。如果你使用的是素数模乘法LCG(其中加法常数为零),这是非常容易做到的。如果席席1=a*Xi% m,则席+n=a*席%m。作为一个具体的例子,考虑具有A=16807和m=23 1-1的PMMLCG。它的最大循环长度为m-1(由于明显的原因,它永远不会产生0),因此我们的目标是迭代m-2次。我们可以使用现成的求幂/模库预先计算am-2%m=1407677000。因此,发现向前步为席+ 1=16807×席%23 1-1,而向后台阶则被发现为XI-1=1407677000×席%23 1-1。
附加的

同样的概念可以扩展到一般的全周期LCG,方法是将转换转换转换为矩阵形式,并进行快速矩阵求幂,从而得到等效的一级转换。席席席1=(a*Xi+c)%m的矩阵公式是席+ 1=t·席%m,其中T是矩阵<代码> [[aC],[0 1 ] ] /> >,x是列向量(x,1)转置。LCG的多次迭代可以通过使用平方和减半幂的快速求幂技术将T提高到任何期望的幂来快速计算。在注意到矩阵T的幂永远不会改变第二行之后,我能够专注于第一行的计算,并在Ruby中生成了以下实现:

def power_mod(ary, mod, power)
  return ary.map { |x| x % mod } if power < 2
  square = [ary[0] * ary[0] % mod, (ary[0] + 1) * ary[1] % mod]
  square = power_mod(square, mod, power / 2)
  return square if power.even?
  return [square[0] * ary[0] % mod, (square[0] * ary[1] + square[1]) % mod]
end
def power_mod(ary、mod、power)
如果幂<2,则返回ary.map{| x | x%mod}
平方=[ary[0]*ary[0]%mod,(ary[0]+1)*ary[1]%mod]
平方=功率×模(平方,模,功率/2)
如果功率相等,则返回平方?
返回[square[0]*ary[0]%mod,(square[0]*ary[1]+square[1])%mod]
结束
其中,
ary
是包含a和c的向量,即乘法和加法系数


通过将
power
设置为循环长度-1,我能够确定产生前一个循环的系数。例如,要使用a=1664525、c=1013904223和m=232“反转”LCG,请使用a=4276115653和c=634785765。您可以很容易地确认后一组系数与使用原始系数生成的序列相反

PRNG(相对于任何随机数字序列)的整体思想是不可逆的。事实上,模运算是“多对一”函数的一个简单例子,根据定义,它排除了可逆性。通过对给定种子和索引的可逆do平均值,找到可能出现的相同种子的随机数(索引-1)?你应该接受这个答案。如果你还没有写一本关于伪随机数生成的书,你应该写一本。谢谢,但是比我聪明得多的人已经写过了。此外,书籍是一项巨大的时间和精力投资,根据这里的投票结果,我怀疑它不会卖出很多书