乱数検証

カルドセプトの乱数問題に触発されて,大学にいたころに作った乱数表示用プログラムをひっぱりだして画像をキャプチャしてみた.

ここでは(bccに備え付けの)randと(よそから引っ張ってきた)MTの一ビット目を比較する.一ビット目が1なら黒,0なら白として,左上から横に一列ずつ結果をドットとして表示している.すなわち,ダイスの目で言うと(rand() % 6 + 1をダイスの目とすれば)ダイスの目が奇数なら白,偶数なら黒で表される.


まずは,普通に表示してみる(上に来る方がrand.場合によっては左右に並ぶかもしれんがその場合は左の方がrand).外枠が白かったり青かったりするのは無視する方向で.



続いて,16回の周期で値を採用してみる(すなわち,15回は空打ちする).



すると,randの方に模様が確認できる.つまり白=0と黒=1の出現にパターンを見出すことができる.


これは線形合同法による乱数生成特有の問題で,特定の周期ではこのように値に偏りができてしまう.さらに,値の偏りは下位ビットで顕著であるため,今回のダイス目のように6で割るような場合には問題として顕在化しやすい.


でも,あれはさすがに偏りすぎな気がする.他に何かやってるのかあるいは乱数関数が相当へぼいのか.最初の画像の組でもわかるように,通常の使用であれば普通のrandでも問題ないが,今回のように乱数が大きな意味を持つ場合はMT(せめてrand-pool)を使うべき.


今回の件では「こんなヘボプログラマーでも業界に入れる」という夢と同時に「ヘボプログラマーだとここまで叩かれる」という現実が突きつけられた感じがする.あと,こういうの見ると大学の講義って大事だったんだなと思う.ソートも大学でやるしね.とはいえ今ならネットだけで同じ勉強ができてしまうわけですが.