続き
モンティ・ホール問題が納得いかなかったので、モンテカルロシミュレーションしてみた
シミュレーションの結果、参加者はドアを変更すると賞品を得られる確率が2倍になるのは明らか。
しかし、やはり納得がいかない。
直感的にわからない。
じゃあ、montyさんが賞品のあるドアの位置を知らなかったらどうなる?
早速、コードを修正してみました。
変更箇所
使用前
if monty_select != select and doors[monty_select] == 0:#賞品が無く、参加者が選ばなかったドアを選ぶ
break
使用後
もしmontyが賞品のあるドアを開けてしまったら、その回はなかったことに。
raiseで例外を投げます。
(あまり綺麗なコードではないですが。)
if monty_select != select:#参加者が選ばなかったドアを選ぶ
if doors[monty_select] != 0:#もしmontyが選んだドアに賞品があったら。その回はなかったことにする。
raise
break
for i in range(n):#指定回数を繰り返す
try:
change += monty(change = True)
except:
change_invalid += 1 #montyが賞品のあるドアを開けてしまった。
try:
nochange += monty(change = False)
except:
nochange_invalid += 1 #montyが賞品のあるドアを開けてしまった。
修正済みコード
import random
import sys
#引数
n = int(sys.argv[1])
#賞を得るのに、成功すると1、失敗すると0を返す
#change ドアを変更するか
#True:変更する
#False:変更しない
def monty(change):
#3枚のドア
doors = [0,0,0]
#乱数でどのドアに賞品があるかを決める
prize = random.randint(0,2)
doors[prize] = 1
#参加者がドアを選ぶ
select = random.randint(0,2)
#続いてmontyがドアを選ぶ
while True:
monty_select = random.randint(0,2)
if monty_select != select:#参加者が選ばなかったドアを選ぶ
if doors[monty_select] != 0:#もしmontyが選んだドアに賞品があったら。その回はなかったことにする。
raise
break
if change:#ドアを変更する場合
while True:
select_change = random.randint(0,2)
if monty_select != select_change and select != select_change:#montyも参加者も選ばないドア
select = select_change
break
if doors[select] == 1:#賞を得られたら1を返す
return 1
return 0#賞が得られなければ0を返す
change = 0
change_invalid = 0
nochange = 0
nochange_invalid= 0
for i in range(n):#指定回数を繰り返す
try:
change += monty(change = True)
except:
change_invalid += 1 #montyが賞品のあるドアを開けてしまった。
try:
nochange += monty(change = False)
except:
nochange_invalid += 1 #montyが賞品のあるドアを開けてしまった。
#結果の表示
print("turn",n)
print("change ",change,"invalid",change_invalid)
print("nochange", nochange, "invalid" ,nochange_invalid)
実行結果
今度は、ドアを変えても変えなくてもほぼ同じになりました。
invalidがmontyが賞品のあるドアを開けてしまって無効となった回数です。
このinvalidの数分に何か原因があるんでしょうけど。
やっぱり直感的には良くわからないですね。。。
turn 1000
change 341 invalid 344
nochange 344 invalid 323
turn 1000
change 325 invalid 346
nochange 382 invalid 313
turn 1000
change 334 invalid 352
nochange 344 invalid 331