四条概率
Four of a Kind
题目详情
从标准 5 张牌手中抽出 4 张同种牌的概率是多少?
What is the probability of drawing 4 of a kind from a standard 5-card hand?
解析
这个问题简化为在扑克牌中获得同种 4 的方法的数量。当处理此类性质的计数问题(扑克手数、服装数量等)时,我发现最好进行概括。在这种情况下,无论同种 4 是 A、2 还是 K,手牌的类型都不受影响。第五张也是最后一张牌可以是剩余 48 张牌中的任何一张。我们可以将一手有效牌概括为:{A A A A B},其中 A 代表一个等级,B 代表任何花色的不同等级。有 13 种有效方法选择 A,因为一副标准牌中有 13 种可能的等级。当我们选完所有 4 张 A 级牌后,还剩下 48 张牌,其中任何一张都可以作为有效的 B 级牌。因此,获得四张牌的方法数为 。
为了证明上述计数方法是有效的,这里有一个替代实现。另一种可能的排列是 {A B B B B},我们首先选择单项,然后选择四项。有 52 种方法可以首先选择我们的单张:它可以是牌组中的任何卡牌。然而,在选择四边形时,它可以是除 A 级以外的任何级别。这是因为 A 级卡只剩下 3 张,无法形成四边形。这给我们留下了 12 个可能的 B 等级。相乘得到了计算有效四手牌的方法数:。
正如你所看到的,无论我们指定四方牌还是单方牌,计算有效手牌的方法数量都是相同的。不过这个问题还没有完成,因为我们被要求计算画出这样一只手的概率。因此,我们必须将有效的四对的数量除以可能的扑克手牌数量。有效扑克牌数由从 52 张牌中选择 5 张牌的方式数给出,即 或 2598960。因此:
import random
import collections
suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
class Deck:
def __init__(self):
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append([rank, suit])
def random_hand(self, size):
# returns a hand with num cards = size
return random.sample(self.cards, size)
deck = Deck()
num_fours = 0
# draw 5 cards from standard deck 1,000,000 times,
# see how many of them result in a 4 of a kind
for i in range(1000000):
hand = deck.random_hand(5)
ranks = [i[0] for i in hand]
# create dictionary with counter of frequency of each suit
count = collections.Counter(ranks)
max_ = max(count.values())
if max_ == 4:
num_fours += 1
# should be expecting 0.00024 * 1,000,000 = around 240
print(num_fours)Original Explanation
This problem reduces to the number of ways to get a 4 of a kind in a poker hand. When approaching counting problems of such a nature (number of poker hands, number of outfits etc.), I find it’s best to generalize. In this case, whether the 4 of a kind is an Ace, a 2, or a King, the type of hand is unaffected. And the fifth and final card can be any of the remaining 48 cards. We can generalize a valid hand as such: {A A A A B}, where A represents one rank, and B represents a different rank of any suit. There are 13 valid ways to choose A, because there are 13 possible ranks in a standard deck of cards. Once we’ve chosen all 4 cards of rank A, there are 48 remaining cards, and any of them can serve as a valid B. As a result, the number of ways to get a four-of-a-kind hand is .
To prove the above counting method is valid, here’s an alternative implementation. Another possible arrangement is {A B B B B}, where we first select our single, and then choose the quad. There are 52 ways to first choose our single: it can be any card in the deck. Then, however, when choosing the quad, it can be any rank except rank A. This is because there are only 3 cards of rank A left, making it impossible to form a quad. That leaves us with 12 possible ranks for B. Multiplying across gives us the the number of ways count a valid four-of-a-kind hand: .
As you can see, the number of ways to count valid hands is equivalent regardless of which rank we assign to be the quad or the single. This problem is not yet complete though because we are asked to compute the probability of drawing such a hand. Thus, we must divide the number of valid four-of-a-kinds by the number of possible poker hands. The number of valid poker hands is given by the number of ways to choose 5 cards from 52, namely or 2598960. Thus:
import random
import collections
suits = ['S', 'C', 'D', 'H']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
class Deck:
def __init__(self):
self.cards = []
for suit in suits:
for rank in ranks:
self.cards.append([rank, suit])
def random_hand(self, size):
# returns a hand with num cards = size
return random.sample(self.cards, size)
deck = Deck()
num_fours = 0
# draw 5 cards from standard deck 1,000,000 times,
# see how many of them result in a 4 of a kind
for i in range(1000000):
hand = deck.random_hand(5)
ranks = [i[0] for i in hand]
# create dictionary with counter of frequency of each suit
count = collections.Counter(ranks)
max_ = max(count.values())
if max_ == 4:
num_fours += 1
# should be expecting 0.00024 * 1,000,000 = around 240
print(num_fours)