【问题标题】:R - Sampling blackjack cardsR - 抽样二十一点卡
【发布时间】:2026-01-24 23:25:01
【问题描述】:

五张牌查理是你抽五张牌而不会破产的地方,即 5 张牌的点数

通过使用 R 的蛮力。我在这里假设有 4 个卡组,这在赌场中很常见,我从这 4 个卡组中抽取 5 张牌,检查他们是否赢了,如果赢了,将其计入概率。谷歌搜索表明它应该在 1/50 左右,即 2%:

deck <- c(rep(1:9, 16), rep(10, 64))
n <- 0 
size <- 1:10e6

for (i in size){
  smpl <- sample(deck,5,replace = F)
  if (sum(smpl) <= 21){
    n <- n+1
  }
}

print(n/max(size) * 100)

[1] 5.98644

请注意,这里的“一副牌”是点数系统,即我们有 1:9 的点数对应 4 套花色,而 4 副牌因此需要 1:9 16 次,类似地,Jack Queen King 和 Ten 都算作 10,但4*4*4 可能的卡片。

抽取5张不放回的牌,检查总和是否

我有两个问题:

1) 我如何修改它,以便我可以采样 1 亿次或更多播放?

2) 6% 的概率我哪里出错了?

【问题讨论】:

  • @Hack-R 我认为链接解释得比我想的要好,但我已经添加了解释。
  • @Hack-R 道歉 - 全部删除!
  • 您的代码似乎假设您在抓手之前重新洗牌/重复使用所有 4 副牌。你也可以在重新洗牌之前使用所有可用的牌,你会得到不同的结果。您还可以包括其他有可能用完您需要的牌并获得甚至不同结果的玩家。当您将 5% 与您在网上找到的 2% 进行比较时,您确定您是在比较苹果和苹果吗?
  • @AdamSampson 重新洗牌/重用是什么意思?你是对的,我假设没有球员。我假设我们有 4 个套牌,我们在这些套牌中随机选择
  • 在赌场你可以抽一手牌,然后重新洗牌,然后抽牌,然后重新洗牌……等等。或者,你可以抽一手牌然后玩,然后再抽一手牌而不重新洗牌,然后再抽一手牌……等等。大多数赌场会随机抽几手牌,然后在您到达牌组尽头之前重新洗牌。在重新洗牌之前,您很少会重新洗牌或抽出整副牌。

标签: r sampling


【解决方案1】:

我认为这里的错误是假设应该是 2%。

您的代码说大约 5%。我改编了existing answer,上面还写着 5%:

deck       <- c(rep(1:9, 4), rep(10, 16))
result     <- combn(deck, 5, function(x) {sum(x) <= 21})

sum(result)/dim(result)
[1] 0.05385693

【讨论】:

  • 谢谢 - 如果您有超过 5 个查理,那么该方法将失败,例如6 因为组合的数量多得离谱。这里的例子也只有一个甲板,除非我误解了
  • @user33484 我以为问题是针对 5 张牌的查理?这与早期的结果相结合,似乎证明了 2% 的数字只是一个错误的假设
【解决方案2】:

对于k = 5, 6, 7 - card charlie,您可以使用replicate 尝试以下操作(通过模拟计算概率):

sapply(5:7, function(k) mean(replicate(n=10^6, 
                           sum(sample(c(rep(1:9, 4), rep(10, 16)), k, replace = F)) <= 21)))
#[1] 0.053943 0.008525 0.000890

这是概率如何随着 k 降低(对于 k-card charlie)

library(ggplot2)
ggplot(aes(card, prob), 
      data=data.frame(card=2:7, prob=sapply(2:7, function(x) mean(replicate(n=10^6, sum(sample(c(rep(1:9, 4), rep(10, 16)),x,replace = F)) <= 21))))) + 
      geom_point() + geom_line()

【讨论】: