モンティ・ホール問題のシミュレーションをしてみる
モンティ・ホール問題という有名な確率の問題があります。
例えばクイズ番組に参加したとする。
最後のボーナスチャレンジで3つの扉のうち、一つに車。
残りはヤギがいたする。見事車の扉を開くことが出来れば車をゲット!
ちなみに司会者は答えを知っている。
まずあなたが選んだのは1の扉。
すると司会者は2, 3の扉のうち3の扉を開けて車が無いことを示した。
次に司会者はあなたに「最初に選んだ扉を変えるか」と聞いてきた。
さぁあなたならどうする!?
そしてその理由は?
これはモンティ・ホール問題と呼ばれ数々の数学者を悩ませてきました。
今回はこれについて解説とシミュレーションの結果を示してみます!
- モンティ・ホール問題の解答と解説
- モンティ・ホール問題のシミュレーションコード
- モンティ・ホール問題シミュレーション結果
- まとめ
モンティ・ホール問題の解答と解説
これの解答は
「変える」
が正解です。
そして解説は
前提となる
- 最初の当たる確率は 1/3
- 司会者は答えを知っている
がポイントです。
まず
1の扉を選びます。
この段階で1の扉で車が当たる確率は 1/3
すると2, 3の扉で当たる確率は 2/3
となります。
扉 | 1 | 2, 3 |
確率 | 1/3 | 2/3 |
次に司会者は 2, 3の扉のうち3の扉を開け、車が無いと示した。
扉 | 1 | 2 | 3 |
結果 | まだわからない | まだわからない | ヤギ |
ここでもう一度最初の表
扉 | 1 | 2, 3 |
確率 | 1/3 | 2/3 |
しかし、3はヤギであることがわかっているので、
3の確率は0
2の確率 + 3の確率 = 2/3 ここで 3の確率 = 0 より 2の確率 = 2/3
扉 | 1 | 2 | 3 |
確率 | 1/3 | 2/3 | 0 |
となり、結果2の方が1と比較しなんと2倍の確率となります!!
つまり、
「最初に選んだ扉から変えたほうが当たる確率が上がる。よって変えるべき」
という結果になります。
数学的に確率論的にこのような解答となりました。
では次にシミュレーションコードを示します
モンティ・ホール問題のシミュレーションコード
今回はrubyで書きました。
def monty(change_flag) gate = ["goat", "goat", "goat"] car = rand(3) gate[car] = "car" first_choice = rand(3) for i in [0,1,2] if i != car and i != first_choice mc_choice = i end end car_flag = 0 if change_flag == 1 for j in [0,1,2] if j != mc_choice and j != first_choice second_choice = j end end if gate[second_choice] == "car" car_flag = 1 end else if gate[first_choice] == "car" car_flag = 1 end end return car_flag end
実行部は
count_change = 0 for i in 1..1000 count_change = count_change + monty(1) end count_nochange = 0 for j in 1..1000 count_nochange = count_nochange + monty(0) end p 'change' p count_change p 'no change' p count_nochange
となります。
さぁ結果はいかに...!?
モンティ・ホール問題のシミュレーション結果
1回目
"change" 674 "no change" 358
2回目
"change" 660 "no change" 321
3回目
"change" 672 "no change" 359
というわけで3回連続で最初に選んだ扉から変更したもののほうが、
約2倍当たっているという結果が得られました。
もし仮に納得のいかない方がいれば是非やってみてください~
まとめ
今回のことで如何に確率が重要な役割を占めているかがわかります。
仮に自分がこのような選択を迫られた時、
2倍の確率で当たる方を常に選択して行きたいと思います。
どんな場面においても確率(当たりやすさ)は存在しています。
これから確率の知識をつけて、不利な戦いは選択しないで生きて行きましょう!!
関連記事
jQueryプラグインの作り方 ~ 重要な3つのポイント ~ - nigoblog
これから先もプログラマーを続けるために重要なこと - nigoblog
プログラマーは今こそアルゴリズムを書くべき!!~モンテカルロ法でπを計算してみよう(コードあり)~ - nigoblog
プログラマーは今こそアルゴリズムを書くべき!!2~再帰アルゴリズムでハノイの塔を解く~ - nigoblog
TDD(テスト駆動開発)でハノイの塔の実装をしてみる~TDD超入門~ - nigoblog
ルービックキューブにハマる~そしてアルゴリズムへ~ - nigoblog
ルービックキューブの実装をPHPでしてみた~ルービックキューブクラス~ - nigoblog