繁体   English   中英

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

[英]Making a customizable LCG that travels backward and forward

我将如何使LCG(伪随机数发生器的类型)在两个方向上传播? 我知道前进是(a*x+c)%m但是我如何才能扭转它呢? 我正在使用它,因此我可以将种子存储在地图上玩家的位置,并可以通过在LCG中向前和向后传播来围绕它生成事物(例如某种随机数线)。

所有LCG都会循环。 在达到最大循环长度的LCG中,每个值x都有一个唯一的前任和一个唯一的后继(对于未达到最大循环长度的LCG或具有子循环行为的其他算法(例如von​​),不一定是正确的。诺伊曼的中平方方法( )。

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

最大的问题是,是否可以将其转换为一个步骤。 如果您使用的是质数模积LCG(加性常数为零),则很容易做到。 如果x i + 1 = a * x i %m,则x i + n = a n * x i %m。 作为一个具体示例,考虑a = 16807和m = 2 31 -1的PMMLCG。 它的最大循环长度为m-1(出于明显的原因它永远不会产生0),因此我们的目标是迭代m-2次。 我们可以使用容易获得的幂/模库预先计算m-2 %m = 1407677000。 因此,前向步长为x i + 1 = 16807 * x i %2 31 -1,而向后步长为x i-1 = 1407677000 * x i %2 31 -1。


额外

通过以矩阵形式转换过渡并进行快速矩阵幂运算以得出等效的一阶段变换,可以将相同的概念扩展到通用的全周期LCG。 x i + 1 =(a * x i + c)%m的矩阵公式为X i + 1 = T·X i %m,其中T为矩阵[[ac],[0 1]] ,X为转置的列向量(x,1)。 通过使用平方和将功率减半的快速求幂技术将T提高到任何所需的功率,可以快速计算LCG的多次迭代。 在注意到矩阵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

其中ary是一个包含a和c的矢量,即乘和加系数。

使用此函数并将power设置为周期长度-1,我能够确定系数,该系数可得出Wikipedia中列出的各种LCG的前身。 例如,要“逆向” a = 1664525,c = 1013904223和m = 2 32的LCG,请使用a = 4276115653和c =634785765。您可以轻松地确认,后一组系数将通过使用原始系数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM