【问题标题】:Non-normal sampling for card shuffling洗牌的非正态抽样
【发布时间】:2021-06-29 15:56:38
【问题描述】:

我有一个脚本,它使用 sample() 将一副牌洗牌到四手 - 如下所示。

这个脚本产生正态分布的手部分裂。也就是说,一套花色中的 13 张牌在四手牌中的分布将在 21.6% 的情况下为“4432”,在 15.5% 的情况下为“5442”,... - 请参见此处:https://en.wikipedia.org/wiki/Contract_bridge_probabilities#Hand%20pattern%20probabilities

有没有办法让sample() 给出非正态分布,例如展平轮廓,使双手的分布偏离预期概率? sample() 可以采用加权参数,但看不到如何使用它来实现我的目标。或者,是否有其他采样功能可以提供此功能?

谢谢,

TC

# Set up
library(tidyverse)
set.seed(123)

# Build pack
pack <- expand.grid(rank = c("A", 2:9, "T", "J", "Q", "K"), suit = c("S", "H", "D", "C")) %>%
  as_tibble(.name_repair = "minimal") %>%
  mutate(card = paste(suit, rank, sep = "-"))

# Divide cards into hands
for (i in 1:4) {
  temp <- sample(pack$card, 13, replace = FALSE) %>%
    as_tibble(.name_repair = "minimal") %>%
    separate(value, sep = "-", into = c("suit", "rank")) %>%
    mutate(
      suit = factor(suit, levels = c("S", "H", "D", "C")),
      rank = factor(rank, levels = c("A", "K", "Q", "J", "T", 9:2, " "))
    ) %>%
    arrange(suit, rank) %>%
    unite("card", sep = "-")

  assign(glue::glue("hand{i}"), temp)
  
  pack <- pack %>%
    filter(!card %in% unname(unlist(temp)))
}

# Reassemble pack
pack <- hand1 %>% 
  cbind(hand2) %>%
  cbind(hand3) %>%
  cbind(hand4) %>% 
  rename(N = 1, E = 2, S = 3, W = 4)

【问题讨论】:

  • sample 使用均匀分布而不是正态分布。
  • 不清楚您要达到的目标。如前所述, sample 使用统一采样技术,因为它旨在处理离散值。从正态分布采样真的只对连续值有意义。您要达到的概率分布到底是什么?如果您不知道您想要的分布,那么也许您应该首先在Cross Validated 寻求统计帮助,因为这可能不是适合 Stack Overflow 的特定编程问题。
  • 我会尽量让你的剧本更像现实。目前,您从已排序的牌组开始,然后使用sample 从牌组中的随机位置抽牌。相反,我建议开发一个shuffle 函数,它可以重新排列牌组,也许“切开”牌组,然后从牌组顶部为每手牌抽牌。然后,您可以尝试不同的shuffle 算法,这些算法会扰乱不同数量的牌组。
  • 例如,deck[rank(1:52 + runif(52, min = -5, max = 12))), ] 将是一种奇怪的随机播放方法。尝试长尾分布,rcauchyrt,...
  • @GregorThomas 和 MrFlick 谢谢。您的 cmets 帮助我澄清了我的问题。它归结为,“我可以更改 sample() 使用的采样方法,允许操纵参数(例如峰度、偏度)或直接应用不同的分布,例如双峰、Cauchy?”。我会进一步调查你的想法。

标签: r probability-distribution


【解决方案1】:

您可以按如下方式简化创建套牌、洗牌和发牌的过程:

# Create the deck
Suit <- c("S", "H", "D", "C")
Rank <- c("A", 2:9, "T", "J", "Q", "K")
Deck <- data.frame(Rank=rep(Rank, 4), Suit=rep(Suit, each=13))

# Shuffle and deal
Shuffle <- Deck[sample(nrow(Deck)), ]  # Shuffle the deck
Hand <- factor(rep(c("N", "E", "S", "W"), 13), levels=c("N", "E", "S", "W"))
Deal <- data.frame(Hand, Shuffle)

现在 deal 是一个显示每手牌的数据框。按花色获取牌的分布:

xtabs(~Suit+Hand, Even)
#     Hand
# Suit N E S W
#    C 3 3 3 4
#    D 3 3 4 3
#    H 3 4 3 3
#    S 4 3 3 3

拿到手:

split(Deal, Deal$Hand)
# $N
#    Hand Rank Suit
# 12    N    Q    S
# 2     N    2    S
# 37    N    J    D
# 49    N    T    C
# 43    N    4    C
# 17    N    4    H
# 33    N    7    D
# 26    N    K    H
# 13    N    K    S
# 44    N    5    C
# 18    N    5    H
# 46    N    7    C
# 11    N    J    S
.  .  .  .  .

由于您提到了手型概率,因此展示如何凭经验生成它们可能会有所帮助:

HPP <- function() {
    Shuffle <- Deck[sample(nrow(Deck)), ]  # Shuffle the deck
    Hand <- factor(rep(c("N", "E", "S", "W"), 13), levels=c("N", "E", "S", "W"))
    Deal <- data.frame(Hand, Shuffle)
    tbl <- xtabs(~Suit+Hand, Deal)
    return(unname(apply(tbl, 1, function(x) paste(sort(x, decreasing=TRUE), collapse="-"))))
}

X <- replicate(1000, HPP())
HP <- prop.table(sort(table(X), decreasing=TRUE))
as.matrix(HP)
#            [,1]
# 4-4-3-2 0.22200
# 5-3-3-2 0.14925
# 5-4-3-1 0.12075
# 4-3-3-3 0.11225
# 5-4-2-2 0.10775
# 6-3-2-2 0.05175
# 6-4-2-1 0.04850
#  .  .  .  .

要按花色获得更“均匀”的牌分布,您必须打破洗牌的随机分布,例如,我们可以洗牌中的排名值,但保留花色的顺序:

Even <- Deck
Even$Rank <- c(replicate(4, sample(Rank)))
Even <- data.frame(Hand, Even)

现在卡值会有所不同,但花色的分配总是一样的。

【讨论】:

  • 谢谢 - 很好的回答。更有效的手牌处理是有用的:速度总是很重要的。但是,您仍在使用未经修改的 Sample(),因此即使随后重新采样,分布也将是正常的。我正在寻找“非正态”分布。如果我无法找到解决方案,我将仔细阅读您的答案,并发布一个更简单的问题 - (例如,多次翻转一对硬币时,获得“HT”/“TH”的可能性是“HH”或“ TT"。我可以对硬币进行偏向吗,例如,让所有 3 个硬币的可能性相同,或者 50% 的时间出现“HH”?)
  • 也许你可以扩大这种方法:flip2 &lt;- c("HH", "HT", "TH", "TT"); table(sample(flip2, 1000, replace=TRUE, prob=c(1/3, 1/6, 1/6, 1/3))),但是有 4 套 13 套会更复杂。
  • 再想一想,随机抽牌然后删除不符合条件的牌会更简单、更快捷。您引用的维基百科页面提供了最常见的套装分布。只需画出 100 只手,并删除不符合您要求的手。如果某些牌为玩家提供不同的优势并且您希望游戏强调技巧而不是运气,这可能是有道理的。
  • “交易 -> 检查特征 -> 保留或重新交易”是个好主意。我走了那条路,但是随着获得特定布局的可能性降低,生成所需的手需要更长的时间。所以,我希望,从一个奇怪的分布开始,然后它应该更快地找到所需的布局。感谢您的帮助。
猜你喜欢
  • 2013-04-28
  • 2012-05-26
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多