梅森旋轉法偽隨機數在delphi下實現

2021-09-26 06:35:07 字數 3557 閱讀 8772

梅森旋轉法(也有翻譯為馬特賽特旋轉演算法)產生的偽隨機數比線性同餘法要好。產生隨機數的速度快、周期長,可達到2^19937-1,且具有623維均勻分布的性質,對於一般的應用來說,足夠大了,序列關聯比較小,能通過很多隨機性測試。現在很多程式語言都預設用梅森旋轉法來提供偽隨機數比如c++從11開始加入了梅森旋轉法,但delphi一直都是用的線性同於法,在xe10.3還是這樣的:

//random integer, implemented as a deterministic linear congruential generator

// with 134775813 as a and 1 as c.

在乙個日本**上找到了現成的梅森旋轉法pascal**,直接儲存為pas檔案即可使用。

使用方法:

procedure tform1.formcreate(sender: tobject);

begin

randomize; //原隨機數初始化

initmt(random(9999999)); //用線性同餘法生成的隨機數來初始化梅森旋轉法

end;

procedure tform1.button1click(sender: tobject);

begin

memo1.lines.add(iranmt.tostring); //獲取乙個梅森旋轉隨機數

end;

梅森旋轉法單元**

unit uranmt;

inte***ce

procedure initmt(seed : longint);

procedure initmtbyarray(initkey : array of longint; keylength : word);

function iranmt : cardinal;

implementation

const

n = 624;

m = 397;

matrix_a = $9908b0df;

upper_mask = $80000000;

lower_mask = $7fffffff;

mag01 : array[0..1] of cardinal = (0, matrix_a);

var mt : array[0..(n-1)] of cardinal;

mti : word;

procedure initmt(seed : longint);

var i : word;

begin

mt[0] := seed and $ffffffff;

for i := 1 to n-1 do

begin

mt[i] := (1812433253 * (mt[i-1] xor (mt[i-1] shr 30)) + i);

mt[i] := mt[i] and $ffffffff;

end;

mti := n;

end;

procedure initmtbyarray(initkey : array of longint; keylength : word);

var i, j, k, k1 : word;

begin

initmt(19650218);

i := 1;

j := 0;

if n > keylength then k1 := n else k1 := keylength;

for k := k1 downto 1 do

begin

mt[i] := (mt[i] xor ((mt[i-1] xor (mt[i-1] shr 30)) * 1664525)) + initkey[j] + j;

mt[i] := mt[i] and $ffffffff;

i := i + 1;

j := j + 1;

if i >= n then

begin

mt[0] := mt[n-1];

i := 1;

end;

if j >= keylength then j := 0;

end;

for k := n-1 downto 1 do

begin

mt[i] := (mt[i] xor ((mt[i-1] xor (mt[i-1] shr 30)) * 1566083941)) - i;

mt[i] := mt[i] and $ffffffff;

i := i + 1;

if i >= n then

begin

mt[0] := mt[n-1];

i := 1;

end;

end;

mt[0] := $80000000;

end;

function iranmt : cardinal;

var y : cardinal;

k : word;

begin

if mti >= n then

begin

if mti = n + 1 then initmt(5489);

for k := 0 to (n-m)-1 do

begin

y := (mt[k] and upper_mask) or (mt[k+1] and lower_mask);

mt[k] := mt[k+m] xor (y shr 1) xor mag01[y and $1];

end;

for k := (n-m) to (n-2) do

begin

y := (mt[k] and upper_mask) or (mt[k+1] and lower_mask);

mt[k] := mt[k - (n - m)] xor (y shr 1) xor mag01[y and $1];

end;

y := (mt[n-1] and upper_mask) or (mt[0] and lower_mask);

mt[n-1] := mt[m-1] xor (y shr 1) xor mag01[y and $1];

mti := 0;

end;

y := mt[mti];

mti := mti + 1;

y := y xor (y shr 11);

y := y xor ((y shl 7) and $9d2c5680);

y := y xor ((y shl 15) and $efc60000);

y := y xor (y shr 18);

iranmt := y

end;

const

init : array[0..3] of longint = ($123, $234, $345, $456);

begin

initmtbyarray(init, 4);

end.

更多**可以在這日本**看到:

梅森旋轉演算法(Mersenne Twister)

梅森旋轉演算法 mersenne twister 也稱馬特賽特旋轉演算法。在python中的random模組就採用該演算法計算隨機數。梅森旋轉演算法 mersenne twister 是乙個偽隨機數發生演算法。由松本真和西村拓士在1997年開發,基於有限二進位製字段上的矩陣線性遞迴。可以快速產生高質...

字元陣列逆序(三步旋轉法)

有乙個字元陣列的內容為 student a am i 請你將陣列的內容改為 i am a student 要求 不能使用庫函式。只能開闢有限個空間 空間個數和字串的長度無關 有乙個字元陣列的內容為 student a am i 請你將陣列的內容改為 i am a student define crt...

可以用旋轉法繪製平行四邊形

很多的數學老師為了使自己的課程更加的生動有趣,往往會在課堂上使用一些輔助教程的軟體,比如幾何畫板 具體的操作步驟如下 步驟一 繪製三角形 開啟幾何畫板,單擊側邊欄 點工具 按住 shift 鍵依次在畫布上面繪製三個點,選中三點並按住 ctrl l 鍵,三角形就製作好了,如下圖所示。在幾何畫板中繪製三...