最初看到這個(gè)問(wèn)題是初中的時(shí)候買(mǎi)了一本有關(guān)數(shù)學(xué)謎題的書(shū)里面概率論的一張的課后拓展就是說(shuō)到三門(mén)問(wèn)題,當(dāng)時(shí)作為一個(gè)擴(kuò)展閱讀看了一下,里面說(shuō)到了一個(gè)世界智商最高的女人秒殺了美國(guó)一大群的數(shù)學(xué)高材生的精彩故事(比較夸張),當(dāng)時(shí)對(duì)這個(gè)問(wèn)題也是似懂非懂。
什么是蒙提霍爾問(wèn)題?

蒙提霍爾問(wèn)題,亦稱(chēng)為蒙特霍問(wèn)題或三門(mén)問(wèn)題(英文:Monty Hall problem),是一個(gè)源自博弈論的數(shù)學(xué)游戲問(wèn)題,大致出自美國(guó)的電視游戲節(jié)目Let's Make a Deal。問(wèn)題的名字來(lái)自該節(jié)目的主持人蒙提·霍爾(Monty Hall)。
最初的表述是:
參賽者會(huì)看見(jiàn)三扇關(guān)閉了的門(mén),其中一扇的后面有一輛汽車(chē),選中后面有車(chē)的那扇門(mén)就可以贏得該汽車(chē),而另外兩扇門(mén)后面則各藏有一只山羊。當(dāng)參賽者選定了一扇門(mén),但未去開(kāi)啟它的時(shí)候,節(jié)目主持人開(kāi)啟剩下兩扇門(mén)的其中一扇,露出其中一只山羊。主持人其后會(huì)問(wèn)參賽者要不要換另一扇仍然關(guān)上的門(mén)。
問(wèn)題是:換另一扇門(mén)會(huì)否增加參賽者贏得汽車(chē)的機(jī)會(huì)率?
這個(gè)古老的問(wèn)題一經(jīng)提出就引起了劇烈的爭(zhēng)論,有人認(rèn)為換與不換最終得到車(chē)的概率都是1/2,有人認(rèn)為換門(mén)之后得到車(chē)的概率更大,應(yīng)該選擇換門(mén)之后得到車(chē)的概率為2/3在撰寫(xiě)這篇文章的時(shí)候在果殼上還有人在為此爭(zhēng)吵,知乎上也有許多關(guān)于這方面的討論,其實(shí)這些爭(zhēng)論很多情況下都是因這個(gè)問(wèn)題的模糊表述所引起的,關(guān)鍵點(diǎn)在于主持人對(duì)于門(mén)后的情況是否了解:
- 如果主持人事先知道哪個(gè)門(mén)里有山羊并且他特意選擇了有山羊的門(mén)打開(kāi)了,那么參賽者應(yīng)該換另一扇門(mén),這可以將他勝利的概率從1/3升到2/3
- 如果主持人事先不知道哪個(gè)門(mén)里有山羊或者他只是隨機(jī)的選擇了一個(gè)門(mén),但事實(shí)發(fā)現(xiàn)里面恰好是山羊。這時(shí)候參賽者沒(méi)有換門(mén)的必要,勝利概率總是1/2
為了后續(xù)的討論,這里采用維基百科上對(duì)于這一個(gè)問(wèn)題的不含糊的定義
嚴(yán)格的表述如下:
- 參賽者在三扇門(mén)中挑選一扇。他并不知道內(nèi)里有什么。
- 主持人知道每扇門(mén)后面有什么。
- 主持人必須開(kāi)啟剩下的其中一扇門(mén),并且必須提供換門(mén)的機(jī)會(huì)。
- 主持人永遠(yuǎn)都會(huì)挑一扇有山羊的門(mén)。
- 如果參賽者挑了一扇有山羊的門(mén),主持人必須挑另一扇有山羊的門(mén)。
- 如果參賽者挑了一扇有汽車(chē)的門(mén),主持人隨機(jī)在另外兩扇門(mén)中挑一扇有山羊的門(mén)。
- 參賽者會(huì)被問(wèn)是否保持他的原來(lái)選擇,還是轉(zhuǎn)而選擇剩下的那一道門(mén)。
那么這個(gè)問(wèn)題這可以很好的理解了,引用維基的一幅圖片解析:

有三種可能的情況,全部都有相等的可能性(1/3):
- 參賽者挑汽車(chē),主持人挑兩頭羊的任何一頭。轉(zhuǎn)換將失敗。
- 參賽者挑A羊,主持人挑B羊。轉(zhuǎn)換將贏得汽車(chē)。
- 參賽者挑B羊,主持人挑A羊。轉(zhuǎn)換將贏得汽車(chē)。
所以玩家選擇換門(mén)之后獲勝的概率應(yīng)為2/3
證明?

定義:
-
事件A
為一開(kāi)始玩家選擇的一扇門(mén) -
事件H
為最后門(mén)后的結(jié)果
- 如果是選擇不換門(mén)的策略
因?yàn)檫x擇的是不交換的策略,所有只有一開(kāi)始選中的是汽車(chē),最后才能選中汽車(chē)。
- 選擇交換門(mén)的策略
因?yàn)檫x擇的是交換的策略,所有只有一開(kāi)始選中的是羊,最后才能選中汽車(chē)。
程序驗(yàn)證
實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),在流言終結(jié)者看到他們?nèi)斯ぶ貜?fù)這個(gè)實(shí)驗(yàn)區(qū)驗(yàn)證,發(fā)現(xiàn)這樣很浪費(fèi)時(shí)間。何通過(guò)計(jì)算機(jī)去去模擬這一段過(guò)程呢?
下面使用python程序來(lái)模擬這一段過(guò)程:
from __future__ import division
import logging
from matplotlib import pyplot as plt
import numpy as np
import random
class MontyHall(object):
"""docstring for MontyHall"""
def __init__(self, num=3):
"""
創(chuàng)建一個(gè)door列表
0 代表關(guān)門(mén)
1 表示后面有車(chē)
-1 代表門(mén)被打開(kāi)
"""
super(MontyHall, self).__init__()
self.doors = [0] * num
self.doors[0] = 1
self.choice = -1
self.exclude_car = False
self.shuffle()
def shuffle(self):
"""
開(kāi)始新游戲
重新分配門(mén)后的東西
"""
if self.exclude_car == True:
self.doors[0] = 1
self.exclude_car = False
for i in xrange(len(self.doors)):
if self.doors[i] == -1:
self.doors[i] = 0
random.shuffle(self.doors)
def make_choice(self):
"""
player隨機(jī)選擇一扇門(mén)
"""
self.choice = random.randint(0, len(self.doors) - 1)
logging.info("choice: %d" % self.choice)
logging.info("original: %s" % self.doors)
def exclude_doors(self):
"""
主持人知道門(mén)后的情況排除門(mén)
直到剩余兩扇門(mén)
"""
to_be_excluded = []
for i in xrange(len(self.doors)):
if self.doors[i] == 0 and self.choice != i:
to_be_excluded.append(i)
random.shuffle(to_be_excluded)
for i in xrange(len(self.doors) - 2):
self.doors[to_be_excluded[i]] = -1
logging.info("final: %s" % self.doors)
def random_exclude_doors(self):
"""
主持人并不知道門(mén)后面的情況隨機(jī)的開(kāi)門(mén)
直到剩余兩扇門(mén)
"""
to_be_excluded = []
for i in xrange(len(self.doors)):
if self.doors[i] != -1 and i != self.choice:
to_be_excluded.append(i)
random.shuffle(to_be_excluded)
for i in xrange(len(self.doors) - 2):
if self.doors[to_be_excluded[i]] == 1:
self.exclude_car = True
self.doors[to_be_excluded[i]] = -1
logging.info("final: %s" % self.doors)
def change_choice(self):
"""
player改變選擇
"""
to_change = []
for i in xrange(len(self.doors)):
if self.doors[i] != -1 and i != self.choice:
to_change.append(i)
self.choice = random.choice(to_change)
logging.info("choice changed: %d" % self.choice)
def random_choice(self):
"""
player 第二次隨機(jī)選擇門(mén)
"""
to_select = []
for i in xrange(len(self.doors)):
if self.doors[i] != -1:
to_select.append(i)
self.choice = random.choice(to_select)
logging.info("random choice : %d" % self.choice)
def show_answer(self):
"""
展示門(mén)后的情況
"""
logging.info(self.doors)
def check_result(self):
"""
驗(yàn)證結(jié)果
"""
got_it = False
if self.doors[self.choice] == 1:
got_it = True
return got_it
模擬1000輪,每一輪重復(fù)試驗(yàn)1000次
- 不改變選擇:
def unchange_choice_test(n):
"""
不改變初始的選擇
"""
result = {}
game = MontyHall()
for i in xrange(n):
game.shuffle()
game.make_choice()
game.exclude_doors()
if game.check_result():
result["yes"] = result.get("yes", 0) + 1
else:
result["no"] = result.get("no", 0) + 1
for key in result:
print "%s: %d" % (key, result[key])
return result["yes"] / n
if __name__ == '__main__':
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.WARNING)
results = []
test_num = 1000
round_num = 1000
for x in xrange(0,round_num):
results.append(change_random_test(test_num) )
y_mean = np.mean(results)
y_std = np.std(results)
x = range(0,round_num)
y = results
plt.figure(figsize=(8,4))
plt.xlabel("round")
plt.ylabel("frequency")
plt.title("The frequency of the success")
tx = round_num / 2
ty = y_mean
label_var = "$\sigma \left( X \\right)=$%f" % y_std
label_mean = "$ X =$%f" % y_mean
p1_label = "%s and %s" % (label_var,label_mean)
p1 = plt.plot(x,y,"-",label=p1_label,linewidth=2)
plt.legend(loc='upper left')
pl2 = plt.figure(2)
plt.figure(2)
plt.hist(results,40,normed=1,alpha=0.8)
plt.show()
結(jié)果:

概率分布:

成功的概率均值在 1/3 附近
- 改變選擇:
def change_choice_test(n):
"""
交換選擇的門(mén)
"""
result = {}
game = MontyHall()
for i in xrange(n):
game.shuffle()
game.make_choice()
game.exclude_doors()
game.change_choice()
if game.check_result():
result["yes"] = result.get("yes", 0) + 1
else:
result["no"] = result.get("no", 0) + 1
for key in result:
print "%s: %d" % (key, result[key])
return result["yes"] / n
同樣的方法繪圖得到結(jié)果:

概率分布:

成功的概率均值在 2/3 附近
通過(guò)上面的分析與模擬可知最佳的策略當(dāng)然就是換門(mén)。
更加深入的討論
- 如果門(mén)的數(shù)量不止是3個(gè),如果是50扇門(mén)呢?

這種情況下,主持人打開(kāi)48扇都是羊的門(mén)后,再給你選擇,很多人這個(gè)時(shí)候應(yīng)該就不會(huì)固守那1/2,而會(huì)選擇換門(mén)
把門(mén)的數(shù)據(jù)增大到100,1000,這種情況會(huì)更加明顯。
還是通過(guò)一段程序模擬說(shuō)明:
def change_choice_test_large(n,m):
"""
交換選擇的門(mén)
"""
result = {}
game = MontyHall(m)
for i in xrange(n):
game.shuffle()
game.make_choice()
game.exclude_doors()
game.change_choice()
if game.check_result():
result["yes"] = result.get("yes", 0) + 1
else:
result["no"] = result.get("no", 0) + 1
for key in result:
print "%s: %d" % (key, result[key])
return result["yes"] / n
if __name__ == '__main__':
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.WARNING)
results = []
test_num = 1000
round_num = 1000
for x in xrange(0,round_num):
results.append(change_choice_test_large(test_num,50) )
結(jié)果:


這時(shí)候就要選擇交換門(mén)。
- 遇到這種情況我很困惑,我決定拋硬幣決定,這個(gè)時(shí)候成功的概率?
這是第3種策略,成功的概率和硬幣有關(guān),也就是1/2,這種情況就是從剩下的門(mén)中隨機(jī)選擇一扇,這個(gè)策略從上面分析來(lái)看不是最好的,但是比不改變的策略要好。
程序的模擬結(jié)果:


- 比如門(mén)意外打開(kāi)的情況呢,也就是上面描述的第二種情況(主持在不知門(mén)后的情況下打開(kāi)門(mén)呢)?
這種情況下其實(shí)就是一個(gè)條件概率,事件A是玩家最后開(kāi)到的是車(chē),事件B是主持人打開(kāi)的門(mén)是羊。
因?yàn)橹挥兄鞒秩碎_(kāi)到是羊的情況下,玩家才有可能開(kāi)到車(chē)所以
設(shè)玩家第一次選擇的門(mén)為事件C
則
- 不交換策略下的條件概率是:
- 交換策略下的條件概率是:
因此在主持人不知道門(mén)后的情況下打開(kāi)一扇,然后發(fā)現(xiàn)門(mén)后是羊的情況下,換門(mén)與不換門(mén)最終的概率都是1/2
還是可以通過(guò)程序進(jìn)行模擬:
def unknown_doors_choice_test(n):
"""
主持人并不知道門(mén)后面的情況隨機(jī)的開(kāi)門(mén)
交換選擇的門(mén)
"""
result = {}
game = MontyHall()
continue_count = 0
for i in xrange(n):
game.shuffle()
game.make_choice()
game.random_exclude_doors()
game.change_choice()
if game.exclude_car == False:
continue_count += 1
if game.check_result():
result["yes"] = result.get("yes", 0) + 1
else:
result["no"] = result.get("no", 0) + 1
#for key in result:
# print "%s: %d" % (key, result[key])
logging.info("continue_count: %d" % continue_count)
if continue_count == 0:
return 0.0
return result["yes"] / continue_count


在這種情況下交換門(mén)也沒(méi)有提升成功的概率
總結(jié)
今天寫(xiě)的這篇東西也算是了解我童年的一個(gè)遺憾,人的直覺(jué)有時(shí)候是很不可靠,要擺脫個(gè)人局限的認(rèn)知才能擁抱更大的世界。
什么?看完這些解析,你還覺(jué)得不滿(mǎn)意那么你還可以從下面的參考中尋找更好的解析,本文撰寫(xiě)過(guò)程有部分的圖片引用自一下的參考,如果你還有疑問(wèn)歡迎你聯(lián)系我進(jìn)一步的討論。
練習(xí)
下面是三門(mén)問(wèn)題的兩個(gè)翻版,引用自三門(mén)問(wèn)題及相關(guān):
女孩的概率
- 你結(jié)交一位新朋友,問(wèn)她是否有孩子。她說(shuō)有,有兩個(gè)。你問(wèn),有女孩嗎?她說(shuō)有。那么,兩個(gè)都是女孩的概率是多少?
答:三分之一。因?yàn)樯鷥蓚€(gè)孩子的可能性有四種等可能:BB、GG、BG、GB(即男男、女女、男女、女男)。 因?yàn)槲覀円阎辽儆幸粋€(gè)女兒,所以BB是不可能的。因此GG是可能出現(xiàn)的三個(gè)等可能的結(jié)果之一,所以?xún)蓚€(gè)孩子都是女兒的概率為三分之一。這對(duì)應(yīng)了三門(mén)問(wèn)題的第一種情況。
- 你結(jié)交一位新朋友,問(wèn)她是否有孩子。她說(shuō)有,有兩個(gè)。你問(wèn),有女孩嗎?她說(shuō)有。第二天,你看見(jiàn)她帶了一個(gè)小女孩。你問(wèn)她,這是你女兒?jiǎn)幔克f(shuō),是。她的兩個(gè)孩子都是女孩的概率是多少?
這個(gè)概率和生女孩的概率相同,二分之一。這似乎非常奇怪,因?yàn)槲覀兯鶕碛械男畔⒖雌饋?lái)并不比第一種情況時(shí)多,但概率卻不同。但是這里的問(wèn)題其實(shí)是,那個(gè)你沒(méi)>見(jiàn)過(guò)的孩子是女孩的概率是多少?這個(gè)概率和生女孩的概率相同,二分之一。
這對(duì)應(yīng)了三門(mén)問(wèn)題的第二種情況。當(dāng)然這里也有語(yǔ)言問(wèn)題,必須假定這位母親不是特定帶出一個(gè)小女孩來(lái)給你看的。也就是說(shuō)你只是碰巧發(fā)現(xiàn)了它是位小女孩。這取決于是判斷選擇 或q 隨機(jī)選擇。如果是被你碰巧撞見(jiàn)這是屬于隨機(jī)選擇。這就對(duì)應(yīng)了三門(mén)問(wèn)題的第二種情況。這其實(shí)是增加了信息的。否則如果她主動(dòng)帶一個(gè)小女孩過(guò)來(lái)給你,則屬于判斷選擇。
你得到的答案依賴(lài)于所講的故事;它依賴(lài)于你是如何得知至少一個(gè)孩子是女孩的。
三囚犯問(wèn)題
- 亞當(dāng)、比爾和查爾斯被關(guān)在一個(gè)監(jiān)獄里,只有監(jiān)獄看守知道誰(shuí)會(huì)被判死刑,另外兩位將會(huì)獲釋。有1/3的概率會(huì)被處死刑的亞當(dāng),給他母親寫(xiě)了一封信,想要獲釋的比爾或查爾斯幫忙代寄。當(dāng)亞當(dāng)問(wèn)看守他應(yīng)當(dāng)把他的信交給比爾還是查爾斯時(shí),這位富有同情心的看守很為難。他認(rèn)為如果他把將要獲釋的人的名字告訴亞當(dāng),那么亞當(dāng)就會(huì)有1/2的概率被判死刑,因?yàn)槭O碌娜撕蛠啴?dāng)這兩人中一定有一個(gè)人被處死。如果他隱瞞這信息,亞當(dāng)被處死的概率是1/3。既然亞當(dāng)知道其他兩人中必有一人會(huì)獲釋?zhuān)敲磥啴?dāng)自己被處死的概率怎么可能會(huì)因?yàn)榭词馗嬖V他其他兩人中被獲釋者的姓名后而改變呢?
正確的答案是:看守不用當(dāng)心,因?yàn)榧词拱勋@釋人的姓名告訴亞當(dāng),亞當(dāng)被處死的概率仍然是1/3,沒(méi)有改變。但是,剩下的那位沒(méi)被點(diǎn)名的人就有2/3的概率被處死(被處死的可能性升高了)。如果這個(gè)問(wèn)題換一種說(shuō)法,就是看守?zé)o意間說(shuō)出了查爾斯不會(huì)死。那么概率就會(huì)發(fā)生改變。
這個(gè)其實(shí)和三門(mén)問(wèn)題是一致的。你可以把獄卒當(dāng)成主持人,被處死當(dāng)成是大獎(jiǎng),那么這個(gè)是對(duì)應(yīng)于三門(mén)問(wèn)題的第一種情況,就是主持人知道門(mén)后面的情況。獄卒說(shuō)出誰(shuí)會(huì)被釋放,相當(dāng)于主持人打開(kāi)一扇門(mén)。但是因?yàn)槿敉絾?wèn)題不能選擇,也就相當(dāng)于三門(mén)問(wèn)題中的不換門(mén)的策略。最終的概率還是1/3是沒(méi)有發(fā)生改變的。
為了避免產(chǎn)生歧義,規(guī)定一下:
1.如果(亞當(dāng),查爾斯)被釋放,那么獄卒會(huì)告訴亞當(dāng):"查爾斯被釋放"。
2.如果(亞當(dāng),比爾)被釋放,那么獄卒會(huì)告訴亞當(dāng):"比爾被釋放"
3.如果(查爾斯,比爾)被釋放,那么獄卒會(huì)以1/2的概率告訴亞當(dāng):"查爾斯被釋放"或者"比爾被釋放"
意思就很明顯了,在獄卒說(shuō)出比爾被釋放的條件下,亞當(dāng)被釋放的概率是?用條件概率算一下。
定義事件:
A :獄卒說(shuō)出"比爾被釋放"
B :代表亞當(dāng)被釋放。

那什么時(shí)候才是1/2的概率呢?
規(guī)則3更改為:如果(查爾斯,比爾)被釋放,那么獄卒會(huì)告訴亞當(dāng)"比爾被釋放"
這個(gè)時(shí)候計(jì)算就是:
![]()
那如果規(guī)則3改為:如果(查爾斯,比爾)被釋放,那么獄卒會(huì)告訴亞當(dāng)"查爾斯被釋放"
這個(gè)時(shí)候:亞當(dāng)被釋放的概率就會(huì)變?yōu)?
問(wèn)題在于規(guī)則2和規(guī)則3下說(shuō)"比爾被釋放"不是等概率發(fā)生的。
類(lèi)似的問(wèn)題還有
- 拋兩枚硬幣其中有一枚硬幣是正面,問(wèn)兩枚硬幣都是正面的概率是?
- 拋兩枚硬幣其中第一枚硬幣是正面,問(wèn)兩枚硬幣都是正面的概率是?
the end.
參考:
更新日志:
- 2015-05-20 增加三囚徒問(wèn)題的解答
- 2015-05-09 第一次撰寫(xiě)