2008年4月20日日曜日

Python: モンティ・ホール問題

このブログ記事をはてなブックマークに追加

モンティ・ホール(Monty Hall)問題とは以下のような問題のことだ。

「プレイヤーは、三つのドアを見せられる。ドアの一つの後ろにはプレイヤーが獲得できる車(アタリ)があり、一方、他の二つのドアには山羊(ハズレ)が入っている。ホストであるモンティは、それぞれのドアの後ろに何があるか知っているのに対し、もちろんプレイヤーは知らない。

プレイヤーはまず三つのドアの一つを選ぶ。次にモンティは他の二つのドアのうち一つを開け、山羊をみせる。そしてモンティはプレイヤーに、初めの選択のままでよいか、もう一つの閉じているドアに変更するか、どちらかの選択権を提供する。プレイヤーは、選択を変更すべきだろうか?」

(モンティ・ホール問題より一部修正)

続きを読む前に、まずは自分で正解を予想して頂きたい。


正解は、「ドアを変更すべき」なのだが、これに引っかかる人は多いらしい。10年ほど前にこの問題を聞いたときは、変更したほうが当たる確率が上がることに気が付いたが、ちょっと考えればそれは当たり前のようにも感じた。一緒に聞いていた人の一人は最後まで納得いかない様子で、こちらが即席で作ったのCのプログラムを実行してみせても信じようとはしなかった。

以下、Pythonでのプログラムを示す。

#!/usr/bin/env python # -*- coding: utf-8 -*- from random import choice DOORS = [1, 2, 3] # ドアの数. N = 1000 # 試行回数. win_picked, win_switch = 0, 0 for i in range(N): # ドアの一つに車を入れる. car = choice(DOORS) # ドアを選ぶ. picked_door = choice(DOORS) # 残りのドアで山羊の入っている方を開ける. open_door = choice(list(set(DOORS) - set([picked_door, car]))) # ドアを変更した場合. switch_door = choice(list(set(DOORS) - set([picked_door, open_door]))) # 車を当てた回数を数える. if picked_door == car: win_picked += 1 elif switch_door == car: win_switch += 1 print u"%d回ゲームを行い、車を当てた割合:" % N print u" ドアを変更しなかった場合: %f %% (%d)" % (100.0 * win_picked / N, win_picked) print u" ドアを変更した場合: %f %% (%d)" % (100.0 * win_switch / N, win_switch)

で、以下のような出力を得る。

1000回ゲームを行い、車を当てた割合: ドアを変更しなかった場合: 33.400000 % (334) ドアを変更した場合: 66.600000 % (666)

0 コメント: