モンティホール問題を解いてみた
探偵ナイトスクープの小ネタ集でモンティホール問題やっていたので、解いてみた。
モンティホール問題とは
登場人物 : Player(あなた), Host(プレゼントくれる人)
- 3つのカップ(A,B,C)の中にプレゼントを用意します。
- Host : 「どれか選んでください」
- Player : 「Aを選びます!」(まだ開けない)
- Host がBを開けます。(Hostはどこにプレゼントが入っているか知っている)
- Host : 「Bには、入ってませんでした。『1. Aを開けますか?』『2.Cにかえますか?』」
このとき,『2.変える』の確率が『1.変えない』の2倍になるという・・・
回答
直感的には1/2で同じ確率になるが、『2.変える』:2/3,『1.変えない』:1/3 の確率になる。
プログラム
Marilyn.py
# coding: utf-8
import random
def do_try(doChange):
# 何も入っていないカップを用意する
cups = {"A":0, "B":0, "C":0}
# プレゼントを一つ格納する
treasure = random.choice(list(cups.keys()))
cups[treasure] = 1
# player: どれかを選ぶ(ランダムで)
choice = random.choice(list(cups.keys()))
# host: 選んだもの と プレゼント 以外のカップを見せる
rest_choice = [v for v in cups.keys() if v != choice and v != treasure]
see_cup = random.choice(list(rest_choice))
# player: 見せられたものを選択肢からはずす。
# player: 「選択肢を変える or 変えない ?」
# doChange = random.choice([True, False])
rest_choice = [v for v in cups.keys() if v != choice and v != see_cup]
final_choice = choice if doChange == False else rest_choice[0]
result = cups[final_choice] == 1
# 選択肢の変更の有無と、宝を引き当てたかを返す
return (doChange, result)
import collections
# player が変えないパターン
array = [do_try(True) for i in range(1,10000)]
print(dict(collections.Counter(array)))
array = [do_try(False) for i in range(1,10000)]
print(dict(collections.Counter(array)))