三門問題——亦稱為蒙提霍爾問題,出自美國的電視游戲節目Let's Make a Deal。問題的名字來自該節目的主持人蒙提·霍爾(Monty Hall)[2]。問題是這樣的:
參賽者面前有三扇關閉着的門,其中一扇的后面是一輛汽車,選中后面有車的那扇門就可以贏得該汽車,
而另外兩扇門后面則各藏有一只山羊。當參賽者選定了一扇門,但未去開啟它的時候,主持人會開啟剩
下兩扇門中的一扇,露出其中一只山羊。主持人其后會問參賽者要不要更換選擇,選另一扇仍然關着的門。

據說此節目一經播出就引起了一場熱烈的討論,有人說應該換,有人認為換不換都一樣。主持人給出的答案是應該換,並在下一期的節目中給出了一個分析表格用來說明她的理由。但這下反對的聲音更大了,在幾千封來信中,反對者達到了9成。[1]
在所有認為該換和不該換的爭論中,正反兩方形成了兩種對立的觀點。
一種是認為不換的中獎幾率是1/3,換的話將有2/3的幾率中獎,因此當然應該換。因為:
根據參賽者的選擇,一共有下面三種可能情況(兩只山羊分別稱為山羊A和山羊B):
(1) 參賽者選擇山羊A,主持人選擇山羊B; (2) 參賽者選擇山羊B,主持人選擇山羊A; (3) 參賽者選擇了汽車,主持人選擇兩只山羊的任何一只
三種情況幾率各為1/3,如果換的話,前兩種都會中獎,僅第三種不會中獎。所以選擇換的中獎概率為2/3,不換幾率只有1/3。
下面再來看看“反方”觀點,這種觀點認為換不換都一樣,幾率都是50%。因為:
當參賽者選擇一扇門時,他中獎的幾率確實只有1/3。但當主持人幫忙排除掉一只山羊時,
車要么在參賽者所選的這個門中,要么在剩下的未被選擇的那扇門中。此時參賽者變更選
擇的話,當然中獎幾率會提升到1/2。
還可以換一個角度來理解。即使他沒有變更選擇,他實際上也做出了選擇,只是選擇的是“不變更”而已。雖然選擇的是“不變”,但不代表他的幾率不變。整個過程重新組織一下會更容易看明白:
(1) 參賽者選了一扇門但不打開 (2) 此時主持人在剩下的兩扇門中選出一扇后面是山羊的門 (3) 然后參賽者在剩下的兩扇門中再次選擇了第一次選擇的門
所以,他選到車的概率為50%。
當然,還有很多“非主流”的觀點,但都經不起推敲,這里不再贅述,感興趣的可以去搜一下。
分析
兩種觀點乍一看好像都很有道理,但它們之中肯定有一個是錯誤的。我認為第一種是正確的,因此分析的重點是解釋為什么另一種答案是錯誤的。並且后面我會編寫程序來驗證答案。
為什么第二種觀點是錯誤的呢?這是因為當我們第一次做出選擇時,所基於的樣本總數為3,此時選定的門后面為汽車的幾率是1/3。並且選定后這一幾率不會再改變(第二種答案正是基於幾率會變的觀點),因為對於已發生的事件來說,后來發生的事件是不可能影響它的幾率的。
千萬不要誤解了上面這句話,這里談到的是幾率,是多次事件的統計結果,並不是確定的一次已發生事件的結果。例如,當把剩下的兩個門都打開后,就能夠確定第一扇門后面是否為汽車,但第一扇門的“幾率”會因此而改變嗎?不會,因為此時我們在談的是特定一次的結果,而不是幾率。如果我們將此過程重復很多次,每次選擇一扇門之后都通過另外2扇門來判斷這扇門后面是不是汽車,我們會發現,此時得到的幾率仍然為1/3。
第二種答案之所以是錯的,還在於它搞錯了一件事情,當我們說“當我們做出選擇時,幾率就隨之確定了”這句話時,實際上是在說“三扇門中任何一扇門后面是汽車的幾率都是1/3”,而不是“我們的選擇決定了這件事的幾率”。我想很多人都搞錯了這一點,一件事的發生幾率是由事物的本質規律決定的,並不會因我們人類的意志為轉移。
所以第一次選擇某個門時,此時的幾率是確定的1/3,當主持人排除掉一扇門之后,第一扇門的幾率絕不會因此而改變,必然仍然是1/3。也許你還有點繞不過這個彎,為此我們來做一個思維實驗:
假設你是參賽者,台上放着三個盒子,其中一個盒子中有獎品,另外兩個是空的。
你首先從三個盒子中隨便選擇一個,然后把所選的盒子抱到一間密封的屋子里面,
但不允許打開盒子,此時主持人在剩下的兩個盒子中打開沒有獎品的那個。試問,
你懷里的盒子的中獎幾率會因此而改變嗎?
是不是有點“薛定諤的貓”的味道?薛定諤的貓是針對量子態的,其真相我們還不得而知,但對宏觀世界來說,我可以負責任地說,盒子中獎的幾率絕對不會改變。
可能你現在已經能夠接受第一次選擇的盒子的中獎幾率不會改變這一結論了。但我知道你肯定還有最后一個疑問,如果不把這個疑問弄清楚,你永遠也不可能真正弄明白這個問題。為此,我們來進行第二個思維實驗:
假設有2個參賽者A和B,參賽者A按照原來的流程先選擇一扇門,此時主持人把一
扇有山羊的門排除掉了。此時又來了一個參賽者B,他並不知道之前發生的事情,
此時他在剩下的兩扇門中隨便選擇一扇門,他的中獎幾率不應該是1/2嗎?也就是
說,剩下的兩扇門的幾率不應該都是1/2嗎?

可能你已經看出來了,這實際上就是對第二種觀點的另一種表述方式,只是把參賽者表述成了A和B 2個人。同樣的2扇門,A和B看到的幾率卻不一樣,這可能嗎?
前面說過,幾率實際上是事物的固有規律,並不以我們的意志為轉移。或者說,世間本沒有“幾率”這個東西,每一件事情都是孤立的、確定的(這里僅討論宏觀),幾率只是經過我們人類的抽象和總結后得到的一個概念。每一次,當三扇門被放到台上時,它的結果都是確定的,而且任何2次相互之間都不會有任何影響。這就像拋硬幣一樣,雖然你可能已經連續拋了100次正面,但你仍然無法肯定下一次是正面還是反面。
回到參賽者A和B的問題上來。他們倆到底哪一個是正確的呢?
答案是2人都對。
但一扇門的幾率怎么可能即是1/3又是1/2呢?這是因為在整個過程中,A比B多掌握了一點信息,A了解到的是:
剩下的2扇門中被排除了一扇
而對B來說,他看到的是:
三扇門中被排除了一扇
正是因為掌握的信息是不對稱的,因此A能夠比B更加准確地做出判斷,進而影響到決策的正確性。也就是說,A“更加正確”,B雖然也沒有錯(題目給他的信息只有那么多,他只能得出對他來說最為正確的判斷),但他卻比A要稍遜一籌。如果抽獎重復很多次,A每次都更換選擇而B是隨機選擇,那么A將大約比B多2/3-1/2=1/6的中獎機會。更有甚者,如果A每次都更換選擇,而B是一個認死理的人,他每次都非要跟A反着干,那么結果將會更慘。
如果說了這么多你心里還保留着一點點疑惑的話,那我再來說一個思維實驗,這個思維實驗是我的“終極武器”,每次跟人討論這個問題的時候,只要一說出這個實驗,爭論立馬就平息了。這個實驗是這樣的:
假設你買了一張彩票,此時上帝出現了,祂對你說,小伙子,看到你買了這么多次
連一次5塊的都沒中過,這次我決定為你排除掉一半不能中獎的號碼。 那么請問,在上帝幫你排除掉那些號碼后,你手里這張彩票的中獎幾率會因此而變
大嗎?如果此時讓你再買一張,你的中獎幾率會變大嗎?
我想答案是不言而喻的。
程序模擬
下面我們用程序來模擬一下,看看到底是怎樣的。
int totalTimes = 1000000; int bingo = 0; boolean[] boxes; for (int i = 0; i < totalTimes; i++) { // loop 1 million times boxes = new boolean[] {false, false, false}; boxes[random(3)] = true; int myChoice = random(3); int hostChoice = openNoPrizeOne(boxes, myChoice); // 判斷另一個盒子是否中獎等同於判斷開始選的盒子沒有中獎 if (!boxes[myChoice]) { bingo++; } } // 更換選擇的中獎幾率 double ratio = (double) bingo * 100 / totalTimes; System.out.println("主持人幫忙排除一個山羊:" + ratio + "%"); return ratio;
其中,random()方法用來生成一個小於參數的隨機非負整數。openNoPrizeOne()用來在剩下的門中排除掉一個山羊。
運行這段程序,可以發現最后的結果確實在2/3附近,例如下面是某次運行的結果:

下面再來看看上面第二個思維實驗中,參賽者A和參賽者B的幾率各是多少:
int totalTimes = 1000000; int bingoA = 0; int bingoB = 0; boolean[] boxes; for (int i = 0; i < totalTimes; i++) { // loop 1 million times boxes = new boolean[] {false, false, false}; boxes[random(3)] = true; int aChoice = random(3); int hostChoice = openNoPrizeOne(boxes, aChoice); // 判斷另一個盒子是否中獎等同於判斷開始選的盒子沒有中獎 if (!boxes[aChoice]) { bingoA++; } // 參賽者B各有1/2的幾率選擇A所選的和剩下的那扇門 boolean isChoiceSameAsA = (random(2) == 1); if (isChoiceSameAsA && boxes[aChoice] || !isChoiceSameAsA && !boxes[aChoice]) { bingoB++; } } // 更換選擇后A的中獎幾率 double ratioA = (double) bingoA * 100 / totalTimes; // 隨機做出選擇的B的中獎幾率 double ratioB = (double) bingoB * 100 / totalTimes; System.out.println("主持人幫忙排除一個山羊,參賽者A:" + ratioA + "%,參賽者B:" + ratioB + "%"); return new double[] {ratioA, ratioB};
下面是某次運行結果:

從代碼中我們可以明顯地看出(參考判斷B是否中獎的if語句):對參賽者B來說,並不是剩下的兩扇門的中獎幾率都為1/2,而是當我們在兩扇門中隨機選擇一扇時的總中獎幾率為1/2。也就是說,B的隨機選擇“調勻”了兩扇門的幾率,實際上此時他的中獎幾率為:
1/2 * 1/3 + 1/2 * 2/3
完整代碼
http://pan.baidu.com/s/1jGyBXjg
參考資料
