一副撲克牌,隨機洗牌後,至少有一組相鄰兩張牌數字相同的概率是多少?
每次在洗撲克牌時,我就會想這個問題. 困擾我很長時間. 因為每次洗牌後,我發現總有至少有兩張數字相同的牌相鄰,所以我認為這是個高概率事件.不知道哪位高手能夠算出確切的概率,感激不盡.
相關問題:一副撲克牌(去掉大小王)。隨機選1~K中的兩個數字,洗牌後將牌扇形攤開,所選兩數的牌相鄰概率? - 概率論
謝邀。
這個問題算確切值是有點困難的,不過有個不錯的方法迅速估算一下,大概只需幾秒鐘。
估算的結果大約是 95.2 %
本題計算結果的補集會比較方便,即:一副撲克牌隨機洗牌後,相鄰牌的數字都不同的概率。
顯而易見,在確定第 1 張牌後,第 2 張牌和其相同的概率是 3/51。
類似地,第 2 張和第 3 張、第 3 張和第 4 張、……、第 51 張和第 52 張相同的概率也是 3/51。以下是第一個近似:把上面 51 個事件看作獨立事件。
顯然,這 51 個事件是相關的,之所以把其看作獨立事件,是因為每一件事情發生的概率都相對較小(雖然 1/17 也是一個不小的數了),因此兩件事情同時發生的概率近似可以看作二階小量。
於是我們要求的補集是
如果學過一點點微積分,應該知道這個公式:
於是我們用到了第二個近似:把 51 看作一個很大的數;
故
所以本題估算的結果大約是 95.2 %
註:上面一個算式也可以直接求結果: 0.95458
這和 @莫濤 算出的精確值只有十萬分之六的差別#(之前的答案有誤,已刪除)在去掉大小鬼的情況下,52張牌中至少有一組相鄰兩張牌數字相同的概率是0.9545237176689056。相應的,任意相鄰兩張牌數字都不同的可能性一共有3668033946384704437729512814619767610579526911188666362431432294400種。
方法:狀態壓縮動態規劃,使用記憶化搜索實現
狀態表示:f(n0, n1, n2, n3, n4, last)為剩餘0張的數字有n0種,剩餘1張的數字有n1種...剩餘4張的數字有n4種,上一張牌現在還剩last張狀態轉移:枚舉下一張牌屬於哪一類,注意和上一張牌不同即可
答案:f(0, 0, 0, 0, 13, 0)代碼:scala/poker.scala at master · mythly/scala · GitHub謝邀
幾位高票答主已經闡述了【求補集】這個思路的好,我來給題主大概算一下【正著求】的難處。
Step1. 首先,我們先解決一個簡單的數學問題:
任意一副隨機洗牌的撲克中(不含大小鬼),一個紅桃A和一個黑桃A相鄰的概率。這個問題簡單吧,剩餘50張牌隨機洗牌共有50!種情況,他們共產生51個空位,兩個A挨著並插入這些空位:P = 2*51*50!/52! = 1/26。Step2.我們計算一下【A?】【A?】【A?】三個A中任意兩個A相鄰的概率。如果你脫口而出3*1/26,恭喜你,你已經可以不用往下看了。
為什麼不是3/26?因為,你會重複數一些情況,而這些情況就是,3個A都相鄰的。他們共有3!*50*49!/52!種,所以P = 3*1/26 - 3!*50*49!/52! = 75/663為什麼重複數了3個A都相鄰的,並重複數了一次呢?為了後續論述的方便,讓我們給一個簡單的證明。我們來考慮3張牌都挨著的6種情況。拿任意一種情況說明,比如,【A?】【A?】【A?】這個順序的情況下,在計算【A?】【A?】和【A?】【A?】時,我們都數了這個情況,所以重複數了一次。Step3.進一步,我們來計算一下【A?】【A?】【A?】【A?】中任意兩個A相鄰的概率,即,一副隨機洗好的撲克牌中,有兩個A相鄰的概率。答案當然不是6*1/26了!能給出這個答案的同學已經在Step2被篩選掉了。那麼,對於4張A有兩個相鄰的情況,我們重複數了哪些呢?首先,我們重複數了所有3張A相鄰的情況,他們是4*3*2*50*49!種。而後,我們重複數了4張A相鄰的情況,他們是4!*49*48!種。所以,減去這些情況的結果 6*1/26 - 4*3*2*50*49!/52! - 4!*49*48!/52! 對么?如果你覺得是對的,可以停止往下看了。看到這裡的聰明的你可能已經發現了3個問題:a、3張牌挨著包含了4張牌挨著;b、4張牌挨著的並不是被重複數了一次,故而減去一次可能不合理;c、即使不是3張牌挨著或4張牌挨著,也有情況被重複數了:4張A兩兩挨著。那麼,為了解決這個問題,我們來看看這些重複的項究竟該被減去幾次?
首先,3張牌挨著,如Step2,他被重複數了一次,故而應該減去一次;4張牌挨著,在6*1/26這個項里,被重複數了3次,在4*3*2*50*49!/52!里被重複數了2次,故而,4張牌挨著已經不用加減了;4張A兩兩挨著,為了避免4張牌挨著被重複計算,我們規定,這個情況只限於4張A兩兩挨著,但他們互相不挨著,這樣的情況共有48!*C(49,2)*4!種(解釋一下,剩餘48張牌洗好,產生49個空位,在49個空位中選2個空位,分別放入兩張AA)。綜上,P = 6*1/26 - 4*3*2*50*49!/52! - 48!*C(49,2)*4!/52! = 1201/5525怎麼知道我們這個數字是對是錯呢?
我們用【求補集】的方法檢驗一下。P = 1 - 48! * A(49,4) / 52! = 1201/5525Step4. 已知,一副隨機洗好的撲克牌中,兩張A挨著的概率是1201/5525,兩張K挨著的概率是1201/5525。求:一副隨機洗好的撲克牌中,兩張A或兩張K挨著的概率。
這個問題我已經難以回答了,因為在2*1201/5525的情況下,被重複計算的情況太多了:AAKK、AAKKAA、AAKKAAKK、AAAKKK等等等等,數不勝數。要計算這個(【正著算】)已經很難了,如果要正著算任意兩張數字相同的牌挨著的概率,可謂難上加難。Step5.已知,一副隨機洗好的撲克牌中,兩張A挨著的概率是1201/5525,兩張K挨著的概率是1201/5525,兩張Q挨著的概率是1201/5525…………兩張2挨著的概率是1201/5525,求:一副隨機洗好的撲克牌中,兩張數字相同的牌挨著的概率。就是這道問題了。
還好,我們有:容斥原理(容斥原理_百度百科):或P = 6*1/26 - 4*3*2*50*49!/52! - 48!*C(49,2)*4!/52! = 1201/5525
現在,我們看看容斥原理能不能幫助我們解決題主的問題。
首先,我們定義6*13=78個集合:{A?和A?相鄰}、{A?和A?相鄰}…………{A?和A?相鄰}、{K?和K?相鄰}、{K?和K?相鄰}…………{K?和K?相鄰}…………{2?和2?相鄰}、{2?和2?相鄰}…………{2?和2?相鄰}。並將他們稱為A1-A78。我們還是要求,根據容斥原理,它應該等於,如果我們願意省略後面的項(他們的數值大都足夠小),看看計算前3項是否能給出一個近似的結果。第一項,78*1/26第二項,兩種情況,一是Ai和Aj的集合里,有一張牌一模一樣,這時,這一項表徵了3張牌相連的個數。概率為13*4*3*2*50*49!/52!;第二種情況,Ai集合中的牌和Aj集合中的牌沒有重複的,概率為:C(78,2)*50!*2*2/52!第三項,很複雜,我們暫時忽略。
所以,P=78/26-13*4*3*2*50!/52!-C(78,2)*50!*2*2/52! = -81/51(看來忽略第三項不行啊)思路就是這樣,我回頭有空的時候討論一下第三項吧。硬廣:隨機 - 知乎專欄蒙特卡羅方法:
import random
all_cards=range(1,14)
all_cards.extend(all_cards)
all_cards.extend(all_cards)
print all_cards
total=1000000
hit=0
for count in range(0,total):
random.shuffle(all_cards)
for card_index in range(0,len(all_cards)-1):
if(all_cards[card_index] == all_cards[card_index+1]):
hit = hit + 1
break
print "%2.2f%%"%(100.0*hit/total)
答案有誤,已經刪除!
講一下我的想法,採用遞推的方法。
首先,我們要計算至少有兩張相鄰的牌數字相同,可以從反方面來考慮,計算任何沒有兩張相鄰的牌數字相同。
下面引入幾個符號:
:1—n數字的牌(每個數字有四張),共4n張,進行排序, 沒有相鄰的兩張牌數字相同,所有排列的個數。:1—n數字的牌(每個數字有四張),共4n張,進行排序,恰有一對相鄰兩張牌數字相同,所有排列的個數。:1—n數字的牌(每個數字有四張),共4n張,進行排序,恰有兩對相鄰兩張牌數字相同,所有排列的個數。:1—n數字的牌(每個數字有四張),共4n張,進行排序,恰有三對相鄰兩張牌數字相同,所有排列的個數。:1—n數字的牌(每個數字有四張),共4n張,進行排序,恰有三對相鄰兩張牌數字相同,所有排列的個數。假設將相同數字,不同花色的牌看成是一模一樣的。
那麼最終我們要求的概率是。 下面來求遞推關係:
解釋:第一項的意思是前4(n-1)張牌已經排好,共有4(n-1)+1個空位可以讓接下來的4張數值為n的牌插入。公式中的第二項也類似,不同的是原來4(n-1)張牌在排序時有相鄰兩張牌是數字相同的,為了達到最後沒有相鄰牌數字相同的問題,必須有一張數值為n的牌插在這裡,因此之後只能是剩下的3張牌插在4(n-1)+1-1個空位中,即。上述公式中的其他幾項也是類似道理,不在贅述。同樣的方法也可以求出的遞推關係。
初值條件:
根據這樣的遞推關係就能求出
最終求出
計算比較複雜,請大神幫忙算算。。。。推薦閱讀:
※如何做好「推薦演算法」?有哪些常見的錯誤需要避免?
※請問隨機森林為什麼不會過度擬合?
※有沒有機器學習方面集大成的教材推薦?
※枚舉和窮儘是不是最有效,最暴力的演算法?
※哪本《數據結構與演算法》最好?