誰しも一度くらいは、乱数生成器を疑似体験1してみたいと思ったことがあるのではないでしょうか?
あなたは乱数が好きですか?私はどちらかと言えば好きよりの人間です。どれくらいかと言えば、三度は思うほどに。飯の代わりになるほどに。
乱数を疑似体験したい、すべての人に贈るゲームを作ってみました。
あなたは乱数生成器ですか?
あなたは乱数生成器ですか?
この記事を読んでいるほとんどの人は、乱数生成器ではないかもしれない。しかし、自分を乱数生成器だと主張する人が現れるかもしれない。そんな時にランダムにキーボードを叩かせて、その結果が非常にランダムだった場合、その人は乱数生成器といっても過言ではないだろう。
それを簡単にできるゲームを提供する(下のリンクから実際に遊べます)。
このゲームの遊び方は簡単だ、0123456789abcdefghijklmnopqrstuvwxyz
をランダムに打つ、ただそれだけ。最後には、入力された乱数がどの程度ランダムかを評価してくれる2。そして、そのスコアを既存のアルゴリズムと比較したランキングが表示される。
評価について
ゲームとして分かりやすい評価が無いか調べていたところ以下のような資料に当たった。その中で「度数検定」「継次検定」「ポーカー検定」の3つが何となく分かりやすそうだったのでその評価手法を参考にした。ただし、統計的に厳密な手法ではなく何となく雰囲気で実装しているため、正しい評価にはなってないと思う。
これらの手法は、乱数生成器が生成した乱数のサンプルを用意してそのサンプルと「完全な乱数であればこうなるだろう」という理論値と比較して、どれだけずれているかを計算する。この際にはカイ二乗検定によってどれくらいズレがあるかを評価する。
ちなみにゲームではこの値を元にスコアを計算しているため、大きければ大きいほど「悪い乱数」という評価になる。
度数検定
0~9a~z は36種類あるため完全にランダムに重複ありで選択した場合、1/36 (2.78%)の確率でそれぞれの文字が出現する。ゲームではプレイヤーが入力した文字を数え上げ、その割合が 1/36 に近いかどうかを計算している。
継次検定
0~9a~z を完全にランダムに2つ選択した場合、その並び順(0->0, 0->1 .... 0->z, .... z->z)は 1/362(0.08%)で出現する。
このゲームでは 200文字しかサンプル数を得られないため、出現回数の期待値が0未満(200 * 0.0008 = 0.16)となってしまい正しく判定できない。そのため 0~9a~z の 36種類を Mod 演算的に 0~8 の9種類に変換している。
こうすることで、ある並び順の出現確率が 1/91(1.23%)になり、200文字の中には 2.5回程度は現れる計算になるため大分マシになった。
ポーカー検定
0~9a~z を完全にランダムに5つ選択すると、ちょうどポーカーの手札のようになる。この時の役(ノーペア、ワンペア、ツーペア、スリーカード、フルハウス、フォーカード、ファイブカード)が出現する確率は計算で求めることができる。
ゲームでは入力された200文字から5個セットの手札を作り、そこに含まれる役を数え上げて期待値と比較する。
こちらも 0~9a~z をそのまま使ってしまうと出現確率の低い役が全く発生しないので、継次検定同様に36種類の文字を 0~8の9種類に変換している。更に、出現確率のかなり低いフォーカードとファイブカードは「フォーカード+」とまとめた。これによってある程度まともにスコアが計算できるようになった。
ちなみに、確率の期待値としては上の表の値を使用している。作り終わってしばらくして気づいたのだが、この確率は 0~9 の数字をランダムに選択したときのものであるがこのゲームでは 0~8 の9種類のため役の出現確率は正しくない....。
1種類の差なので恐らく大きくずれているとは思えないが、検定としては全く正しくない評価になってしまっている。
ここはゲームということで許して......
Twitter で結果をシェアできるようにしてみた
せっかくゲームを作ったのだから、結果を Tweet する機能も作ってみてみたい!ということで、シェアボタンを設置してみた。
このボタンから Tweet すると、プレイヤーが入力した乱数列が埋め込まれたリンクがシェアされるため、それを開くことで結果を再現できる。
ランキングにいる他の乱数(?)たちは、実際にプレイヤーに行っている評価を計算しているが seed を固定して毎回同じ値になるように工夫もしてみた。
ソースコード
参考
- 長崎大学学術研究成果リポジトリ 乱数の検定について