You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何两段R代码计算21点天然牌概率结果存在差异?

为何两种牌组定义方式导致21点天然牌概率计算结果不同?

我用R语言模拟牌组研究概率时发现:当牌组用数字字符串(如"10"、"8")构建时,计算21点天然牌的概率,和用纯字符字符串(如"Ten"、"Eight")构建的结果不一样。

加载library(gtools)后,第一段代码如下:

suits <- c("D", "C", "H", "S")
numbers <- c("2", "3", "4", "5", "6", "7", "8", "9", "10", 
             "J", "Q", "K", "A")
deck <- expand.grid(number = numbers, suit = suits)
deck <- paste(deck$number, deck$suit)
aces <- paste("A", suits)

facecard <- c("K", "Q", "J", "10")
facecard <- expand.grid(number=facecard, suit=suits)
facecard <- paste(facecard$number, facecard$suit)

hands <- combinations(52, 2, v = deck)

mean(hands[,1] %in% aces & hands[,2] %in% facecard)

运行结果:

> mean(hands[,1] %in% aces & hands[,2] %in% facecard)
[1] 0.0361991

换成纯字符字符串定义numbers后,代码如下:

suits <- c("D", "C", "H", "S")
numbers <- c("Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", 
             "Ten", "J", "Q", "K", "A")
deck <- expand.grid(number = numbers, suit = suits)
deck <- paste(deck$number, deck$suit)

aces <- paste("A", suits)

facecard <- c("K", "Q", "J", "Ten")
facecard <- expand.grid(number=facecard, suit=suits)
facecard <- paste(facecard$number, facecard$suit)

hands <- combinations(52, 2, v = deck)

mean(hands[,1] %in% aces & hands[,2] %in% facecard)

运行结果:

> mean(hands[,1] %in% aces & hands[,2] %in% facecard)
[1] 0.04826546

问题

为什么只是把numbers向量换成纯字符字符串,概率计算结果就出现差异?是因为"A"和其他数字的组合导致花牌计数减少吗?

解答

差异完全源于combinations()函数的排序特性:

gtools包中的combinations()函数生成组合前,会先对输入的向量v按字符串顺序排序,再生成有序的组合对——每个无序牌组只会出现一次,且组合内元素按排序后的顺序排列(靠前的元素在第一列,靠后的在第二列)。

两种场景的具体差异:

  1. 数字字符串场景:
    字符串排序时,"10"的首字符"1"ASCII码小于"A"的"A",所以"10 D"这类牌会排在"A D"前面;而"J"、"Q"、"K"的ASCII码大于"A",会排在"A"后面。
    因此:

    • A和"10"类花牌的组合会以花牌在前、A在后的形式出现(比如("10 D", "A D")),不会被你的hands[,1] %in% aces条件命中;
    • A和J/Q/K类花牌的组合会以A在前、花牌在后的形式出现,会被统计到。
      最终有效统计数是4张A × 12张J/Q/K花牌 = 48,除以总组合数C(52,2)=1326,得到≈0.0361991。
  2. 纯字符字符串场景:
    "Ten"的首字符"T"ASCII码大于"A",所以所有花牌(Ten、J、Q、K)都排在A牌后面。
    所有A和花牌的组合都会以A在前、花牌在后的形式出现,全部被你的条件统计到,有效统计数是4×16=64,除以1326得到≈0.04826546。

补充:正确的天然牌概率计算

21点天然牌包含A+花牌和花牌+A两种无序组合,但combinations()只会生成一次每个无序对。如果要统计完整的天然牌概率,应该同时覆盖两种排列形式的组合:

mean((hands[,1] %in% aces & hands[,2] %in% facecard) | (hands[,1] %in% facecard & hands[,2] %in% aces))

此时两种场景下的结果会一致,均为天然牌的真实概率≈0.04826546。

内容的提问来源于stack exchange,提问作者nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:05:29