簡體   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