从 5 张手牌扑克中获得对子的概率
Probability to get pair from 5-card hand poker
我需要通过模拟找到从 5 张手牌中得到一对牌的概率百分比。
到目前为止,我已经制作了 类 "Card"(功能:卡片价值、花色、按价值与另一张卡片进行比较)和 "Hand"(功能:addCard 和 isOnePair returns 仅当手牌实例中有一对牌时才为真。
Card.java:
public enum CardValue { s2, s3, s4, s5, s6, s7, s8, s9, s10, J, Q, K, A }
public enum CardSuit { C, D, H, S }
private CardValue value;
private CardSuit suit;
public Card(CardValue value, CardSuit suit) {
this.value = value;
this.suit = suit;
}
@Override
public boolean equals(Object obj) {
if(obj == this) {
return true;
}
if(!(obj instanceof Card)) {
return false;
}
Card card = (Card)obj;
return card.value == this.value;
}
Hand.java
private Set<Card> hand;
public Hand() {
this.hand = new HashSet<>();
}
public void addCard(Card card) {
this.hand.add(card);
}
@Override
public String toString() {
return this.hand.toString();
}
private boolean isOnePair() {
int counter = 0;
for(Card card : hand){
for(Card card2 : hand) {
if(card.equals(card2)) {
counter++;
}
}
if(counter == 2) {
return true;
}
counter = 0;
}
return false;
}
- 首先,创建一个包含所有可能的
Card
的 List
套牌。
- 然后,对于模拟的每次迭代,洗牌并抽取前 5
Card
s。
- 检查是否有一对,如果有,增加一个计数器。
- 将计数器除以迭代总数。
示例:
Random rand = new Random();
final int NUMBER_OF_VALUES = Card.CardValue.values().length;
final int NUMBER_OF_SUITS = Card.CardSuit.values().length;
final int NUMBER_OF_CARDS_IN_HAND = 5;
Card.CardValue value;
Card.CardSuit suit;
Hand hand;
List<Card> deck = new ArrayList<>();
// Deck creation
for(int i = 0; i < NUMBER_OF_VALUES; i++) {
for(int j = 0; j < NUMBER_OF_SUITS; j++)
deck.add(new Card(Card.CardValue.values()[i], Card.CardSuit.values()[j]));
}
int counter = 0;
final int TOTAL = 100000;
// Simulation
for(int i = 0; i < TOTAL; i++) {
Collections.shuffle(deck);
hand = new Hand();
for(int j = 0; j < NUMBER_OF_CARDS_IN_HAND; j++)
hand.addCard(deck.get(j));
if(hand.isOnePair()) counter++;
}
System.out.println("Probability: " + 100 * counter / (double)TOTAL + "%");
你只关心有52张牌,它们平均分布在13个等级上。您不需要模拟甲板。您只想选择 0 到 51 之间的 5 个随机数,不要重复,然后计算一个数字的排名与另一个数字的排名匹配的次数,考虑到排名在 52 个可选数字中按顺序重复 4 次。如果这种情况只发生一次,您就有一对牌。这只需要 5 次迭代的一个循环。
此代码通过 运行 200K 次迭代来估计 5 张手牌中恰好一对的概率。它在我的 Macbook Pro 上几乎是瞬间完成的:
import java.util.Random;
public class OnePair {
// Initialize a random number generator
private static Random random = new Random(System.currentTimeMillis());
private static boolean doOne() {
// Keep track of cards we've picked so we don't pick the same card twice
boolean[] cards = new boolean[52];
// Keep track of ranks we've seeen before
boolean[] ranks = new boolean[13];
// Keep track of how many times ranks have matched
int count = 0;
// For each of 5 cards...
for (int i = 0 ; i < 5 ; i++) {
// Pick a random card we haven't picked before
int card;
while (true) {
card = random.nextInt(52);
if (!cards[card]) {
cards[card] = true;
break;
}
}
// If we've seen this rank before, increase our total matches
if (ranks[card % 13])
count += 1;
// Remember that we've seen this rank
ranks[card % 13] = true;
}
// Return if we saw exactly one pair, in which case count will be 1
return count == 1;
}
public static void main(String[] args) {
long count = 200000;
long paired = 0;
for (int i = 0 ; i < count ; i++)
if (doOne())
paired += 1;
System.out.println((float)paired / count);
}
}
我得到的结果抽样:
0.42265
0.42181
0.42112
0.422675
0.423895
我找到了同样问题的统计计算,规定的概率是 0.422569。
我需要通过模拟找到从 5 张手牌中得到一对牌的概率百分比。
到目前为止,我已经制作了 类 "Card"(功能:卡片价值、花色、按价值与另一张卡片进行比较)和 "Hand"(功能:addCard 和 isOnePair returns 仅当手牌实例中有一对牌时才为真。
Card.java:
public enum CardValue { s2, s3, s4, s5, s6, s7, s8, s9, s10, J, Q, K, A }
public enum CardSuit { C, D, H, S }
private CardValue value;
private CardSuit suit;
public Card(CardValue value, CardSuit suit) {
this.value = value;
this.suit = suit;
}
@Override
public boolean equals(Object obj) {
if(obj == this) {
return true;
}
if(!(obj instanceof Card)) {
return false;
}
Card card = (Card)obj;
return card.value == this.value;
}
Hand.java
private Set<Card> hand;
public Hand() {
this.hand = new HashSet<>();
}
public void addCard(Card card) {
this.hand.add(card);
}
@Override
public String toString() {
return this.hand.toString();
}
private boolean isOnePair() {
int counter = 0;
for(Card card : hand){
for(Card card2 : hand) {
if(card.equals(card2)) {
counter++;
}
}
if(counter == 2) {
return true;
}
counter = 0;
}
return false;
}
- 首先,创建一个包含所有可能的
Card
的List
套牌。 - 然后,对于模拟的每次迭代,洗牌并抽取前 5
Card
s。 - 检查是否有一对,如果有,增加一个计数器。
- 将计数器除以迭代总数。
示例:
Random rand = new Random();
final int NUMBER_OF_VALUES = Card.CardValue.values().length;
final int NUMBER_OF_SUITS = Card.CardSuit.values().length;
final int NUMBER_OF_CARDS_IN_HAND = 5;
Card.CardValue value;
Card.CardSuit suit;
Hand hand;
List<Card> deck = new ArrayList<>();
// Deck creation
for(int i = 0; i < NUMBER_OF_VALUES; i++) {
for(int j = 0; j < NUMBER_OF_SUITS; j++)
deck.add(new Card(Card.CardValue.values()[i], Card.CardSuit.values()[j]));
}
int counter = 0;
final int TOTAL = 100000;
// Simulation
for(int i = 0; i < TOTAL; i++) {
Collections.shuffle(deck);
hand = new Hand();
for(int j = 0; j < NUMBER_OF_CARDS_IN_HAND; j++)
hand.addCard(deck.get(j));
if(hand.isOnePair()) counter++;
}
System.out.println("Probability: " + 100 * counter / (double)TOTAL + "%");
你只关心有52张牌,它们平均分布在13个等级上。您不需要模拟甲板。您只想选择 0 到 51 之间的 5 个随机数,不要重复,然后计算一个数字的排名与另一个数字的排名匹配的次数,考虑到排名在 52 个可选数字中按顺序重复 4 次。如果这种情况只发生一次,您就有一对牌。这只需要 5 次迭代的一个循环。
此代码通过 运行 200K 次迭代来估计 5 张手牌中恰好一对的概率。它在我的 Macbook Pro 上几乎是瞬间完成的:
import java.util.Random;
public class OnePair {
// Initialize a random number generator
private static Random random = new Random(System.currentTimeMillis());
private static boolean doOne() {
// Keep track of cards we've picked so we don't pick the same card twice
boolean[] cards = new boolean[52];
// Keep track of ranks we've seeen before
boolean[] ranks = new boolean[13];
// Keep track of how many times ranks have matched
int count = 0;
// For each of 5 cards...
for (int i = 0 ; i < 5 ; i++) {
// Pick a random card we haven't picked before
int card;
while (true) {
card = random.nextInt(52);
if (!cards[card]) {
cards[card] = true;
break;
}
}
// If we've seen this rank before, increase our total matches
if (ranks[card % 13])
count += 1;
// Remember that we've seen this rank
ranks[card % 13] = true;
}
// Return if we saw exactly one pair, in which case count will be 1
return count == 1;
}
public static void main(String[] args) {
long count = 200000;
long paired = 0;
for (int i = 0 ; i < count ; i++)
if (doOne())
paired += 1;
System.out.println((float)paired / count);
}
}
我得到的结果抽样:
0.42265
0.42181
0.42112
0.422675
0.423895
我找到了同样问题的统计计算,规定的概率是 0.422569。