首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >洗牌的非正态抽样

洗牌的非正态抽样
EN

Stack Overflow用户
提问于 2021-06-29 23:56:39
回答 1查看 42关注 0票数 0

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

此脚本生成正态分布的手部分割。这是在一套花色中的13张牌在四手中的分布将是"4432“21.6%的时间,"5442”15.5%的时间,... -请参阅此处:https://en.wikipedia.org/wiki/Contract_bridge_probabilities#Hand%20pattern%20probabilities

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

谢谢,

TC

代码语言:javascript
运行
复制
# 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)
EN

回答 1

Stack Overflow用户

发布于 2021-06-30 06:54:50

您可以简化创建卡片组、洗牌和处理的过程,如下所示:

代码语言:javascript
运行
复制
# 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)

现在发牌是一个数据框,显示了每一手中的牌。要获得按花色分配的卡片,请:

代码语言:javascript
运行
复制
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

要获得手,请执行以下操作:

代码语言:javascript
运行
复制
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
.  .  .  .  .

既然您提到了手部模式概率,那么展示如何根据经验生成它们可能会很有帮助:

代码语言:javascript
运行
复制
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
#  .  .  .  .

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

代码语言:javascript
运行
复制
Even <- Deck
Even$Rank <- c(replicate(4, sample(Rank)))
Even <- data.frame(Hand, Even)

现在,牌值会有所不同,但花色的分配总是相同的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68182103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档