見出し画像

PowerShellの乱数ランダム性テスト

お馴染みの6面体サイコロを振ると、どの面が出るかは6分の1です。
(完全な6面体の場合)

でも、これをコンピュータ上で行うと確率6分の1にならない。
コンピュータに詳しい人には説明不要だと思いますが6分の1にならないんです。
昔のパソコンでBASIC言語を使ってサイコロを振ると1が多く出ていた記憶があります。

最近のパソコンだとどうなんでしょうか
PowerShellで確認してみました。

下に0から9までの乱数を100万回を起こして数をカウントするプログラムを書いてみました。


$n=10                # 0から変数n-1 まで乱数を起こす
$loopcnt=1000000     # この数だけ乱数を作る
$numcounter=@(0)*$n  # 乱数のカウンター

for($i=0;$i -lt $loopcnt;$i++){
	$num = Get-Random -max $n -min 0
	$numcounter[$num]+=1
}

for($i=0;$i -lt $n;$i++){
	write-host $i " は " $numcounter[$i] " 回"
}


何度か実行しました。
どれかの数字に偏ることはなかったです。

しかし、100万回も乱数を起こしたら
それぞれの数字が出る回数が10万づつになるハズなんですけども。
ならないですね。

そこで1000万回乱数を起こすように書き換えて実行してみました。

1000万回の乱数でも結果は同じ。
それぞれの数字が出る回数が同じ回数になるハズなんですけども、ならないですね。数学的には不正確?ですかね。
昔のパソコンだと1000万回も乱数を起こすと数字1が飛び抜けて多く出る結果になっていました(記憶違いで4だったかも)。だから今のパソコンはそこそこの正確性はあると思っていいかもしれません。


1億回乱数を起こすように書き換えて試してみました。
途中の経過も見れるようにちょっと改造してみました。

$n=10                # 0から変数n-1 まで乱数を起こす
$loopcnt=100000000   # この数だけ乱数を作る
$numcounter=@(0)*$n  # 乱数のカウンター

for($i=0;$i -lt $loopcnt;$i++){
	$num = Get-Random -max $n -min 0
	$numcounter[$num]+=1

    if($i%100000 -eq 0) {
        write-host " "
        for($j=0;$j -lt $n;$j++){
	        write-host $j " は " $numcounter[$j] " 回"
        }
    }
}

write-host " "
for($j=0;$j -lt $n;$j++){
    write-host $j " は " $numcounter[$j] " 回"
}


1億回の乱数でも結果は同じ。
それぞれの数字が出る回数が同じ回数になるハズなんですけども、ならないですね。しかし途中の結果を観察しても、だいたい同じような確率になっています。







結論
・乱数を繰り返し起こしても、どれかの数字に偏ることはない
・完全にランダムではないが、だいたいランダムになっている
・昔のパソコンは酷い


乱数についての資料はこちら

[あなたの使っている乱数、大丈夫? 第50回市村学術賞記念 先端技術講演会 松本 眞]

http://www.math.sci.hiroshima-u.ac.jp/m-mat/TEACH/ichimura-sho-koen.pdf

乱数の品質を検定する方法について書かれた論文もありました。

[講座 シミュレーションのための乱数入門 4. 乱数の品質と検定法]

https://www.jspf.or.jp/Journal/PDF_JSPF/jspf2020_07/jspf2020_07-372.pdf



#PowerShell #8ビットパソコン #プログラミング初心者 #プログラミング学習 #乱数




いいなと思ったら応援しよう!