5

昨晚看了squid游戏电视剧第7集。这一集在桥上有一个二项式分布的游戏。

在此处输入图像描述

具体来说,有16名玩家,一座桥上有18副眼镜(一副纯玻璃和一副安全玻璃)。如果一个玩家碰巧选择了纯玻璃,那么玻璃无法承受玩家的重量,玻璃破裂了。下一个玩家的优势是他/她从上一个玩家的位置开始并继续二项式搜索。最后3个玩家碰巧过桥。

所以我想知道:就像,我口袋里有 16 欧元,我在玩正面或反面p = 1/2。每次我都押在正面。如果硬币翻转是正面,那么我赚 0,如果是反面,我损失 1 欧元。击中 18 次(连续或不连续)正面并在我的口袋里留下 3 欧元的概率是多少?

我试图在 R 中模拟这个问题:

squid_bridge = function(a,n,p) {
  players = a
  while (position > 0 & position < n) {
    jump  =  sample(c(0,1),1,prob=c(1-p,p))
    position = position + jump
  }
  if (position == 0) 
    return(1) 
  else 
    return(0)
}   

n = 18
trials = 100000
a = 16
p = 1/2
set.seed(1)
simlist = replicate(trials, squid_bridge(a, n, p))

它似乎不起作用。有什么帮助吗?

4

5 回答 5

3

○ △ □</p>

##########
# Game ○ △ □ 
##########
squidd7<-function(N_Fields,N_Players,p_new_field){
  Players<-data.frame(id = 1:N_Players, alive=rep(1,N_Players),Field=0)
  
    for(i in 1:N_Players){
      while (Players[i,"alive"]==TRUE && max(Players$Field)< N_Fields) { 
        Players[i,"Field"]=Players[i,"Field"]+1  # Jump onto the next Field
        Players[i,"alive"]=rbinom(1,1,p_new_field)# Fall or repeat
      }
      Players[i+1,"Field"]=Players[i,"Field"] # next player starts where prior player died
    }
  Players<-Players[1:N_Players,] # cosmetic because i do i+1 in the prior line
  # Print me some messages
  if(!any(Players$alive>0)){
      cat("Players loose!")
    } else {
    cat(" \n After", max(Players$Field),"goal was reached! ")
    cat("Players",Players[Players$alive==1,"id"], "survive")
    }
  
  return(Players)
}


squidd7(18,16,0.5)

###########
# simulation ○ △ □
###########
results<-data.frame(matrix(0, nrow = 100, ncol = 20))
for(x in 1:ncol(results)){
     for (i in 1:nrow(results)) {
    Players<-squidd7(x+7,16,0.5)
    results[i,x]<-sum(Players$alive)
  }
}
###########
## Results ○○□□○ △ □
sdt<-apply(results,2,sd) # standart devation 
mn<-apply(results,2,mean) # ○ △ □

boxplot(results,xlab ="n Steps ",names = 8:27,ylab="N Survivors of 16 ")
points(mn,type="l")
points(sdt,type="l")

colors<-colorRampPalette(c(rgb(0,1,0,0.4),
                           rgb(1,1,0,0.4),
                           rgb(1,0,0,0.4)), alpha = TRUE)(21)


plot(density(results$X1),type="n",xlim=c(-1,17),ylim=c(0,0.30),
     main="○ △ □ ",
     sub="○ △ □ ○ △ □ ○ △ □&quot;,
     xlab="number of survivors")
for( i in 1:21){
polygon(density(results[,i]),col= colors[i])
}
legend(15,0.31,title="Steps",legend=8:28,fill=colors,border = NA,
       y.intersp = 0.5,
       cex = 0.8, text.font = 0.3)

于 2021-10-16T21:13:46.093 回答
3

以下是我认为您可以在 R 中对游戏进行建模的方法。第一个版本与您所拥有的类似:有 50% 的机会猜对,如果猜对了,玩家就会推进一个牌。否则他们不这样做,并且玩家人数减1。如果玩家人数达到0,或者他们前进到最后,则游戏结束。这显示在 中squid_bridge1()

squid_bridge1 <- function(players, n, prob) {
  if (players == 0 | n == 18) {
    # All players have died or we have reached the end
    return(players)
  }
  
  jump <- rbinom(1, 1, prob)
  
  if (jump == 0) {
    # Player died
    return(squid_bridge1(players - 1, n, prob))
  }

  if (jump == 1 & n < 18) {
    # Player lives and advances 1 space
    return(squid_bridge1(players, n + 1, prob))
  } 
}

然而,这并不能准确地描述游戏,因为错误的猜测会给剩余的玩家额外的信息。如果玩家选择错误,那么下一次猜测正确的概率不是 50%,而是 100%。但是,在那之后,正确猜测的概率会降低到 50%。这可以用另一个参数来解释,以跟踪先前猜测的正确性。

squid_bridge2 <- function(players, n, prob, previous) {
  if (players == 0 | n == 18) {
    # The game ends if there are no players or they have reached the end
    return(players)
  }
  
  if (previous == 0) {
    # The previous guess was wrong, but now the players know where to go next
    return(squid_bridge2(players, n + 1, prob, previous = 1))
  }
  
  jump <- rbinom(1, 1, prob)
  
  if (jump == 0) {
    # Player died
    return(squid_bridge2(players - 1, n, prob, previous = 0))
  }
  
  if (jump == 1 & n < 18) {
    # Move is correct. Advance 1 space
    return(squid_bridge2(players, n + 1, prob, previous = 1))
  } 
}

但是,有一个问题。在节目中并不是那么简单,玩家摔倒的原因不是错误的猜测(被推,故意跳跃等)。我不知道做这样的事情的合理概率是多少,但它可能很低,比如说 10%。

not_stupid <- function() {
  x <- runif(1, 0, 1)
  if (x <= 0.1) {
    return(FALSE)
  } else {
    return(TRUE)
  }
}

由于情绪在每次移动之前都会飙升,因此我们将在每次移动之前进行测试。

squid_bridge3 <- function(players, n, prob, previous) {
  if (players == 0 | n == 18) {
    # The game is over because there are no players left or they reached the end
    return(players)
  }
        
  if (previous == 0) {
    # The previous guess was wrong, but now the players know where to go next
    return(squid_bridge3(players, n + 1, prob, previous = 1))
  }
  
  if (!not_stupid()) {
    return(squid_bridge3(players - 1, n, prob, previous = 1))
  }
  
  jump <- rbinom(1, 1, prob)
  
  if (jump == 0) {
    # Player died because of either choosing wrong or a self-inflicted loss
    return(squid_bridge3(players - 1, n, prob, previous = 0))
  }
  
  if (jump == 1 & n < 18) {
    # Move is correct. Advance 1 space
    return(squid_bridge3(players, n + 1, prob, previous = 1))
  } 
}

然后运行一些模拟:

set.seed(123)
trials <- 10000
players <- 16
squid1 <- replicate(trials, squid_bridge1(players, 0, 0.5))
squid2 <- replicate(trials, squid_bridge2(players, 0, 0.5, 1))
squid3 <- replicate(trials, squid_bridge3(16, 0, 0.5, 1))

df <- tibble(squid1 = squid1,
             squid2 = squid2,
             squid3 = squid3) %>%
  pivot_longer(cols = c(squid1, squid2, squid3))

ggplot(data = df,
       aes(x = value)) +
  geom_histogram(bins = 10,
                 binwidth = 1,
                 fill = "cornflowerblue",
                 color = "black") +
  facet_wrap(~name,
             nrow = 3) +
  xlab("# of players to make it to the end") +
  scale_x_continuous(breaks = seq(0, 16, by = 1),
                     labels = seq(0, 16, by = 1))

正如您在下面看到的,第一种情况严重偏左。由于玩家基本上是在“盲目地猜测”每一块牌,因此任何人都不太可能走到最后。然而,在考虑了从错误猜测中获得的信息后,平均大约有 7 名玩家成功。通过添加由于另一个原因而随机下降的机会,分布会向左倾斜一些。

  • 第一种情况的平均值:1.45
  • 第二种情况的平均值:7.01
  • 第三种情况平均值:4.99

在此处输入图像描述

要回答只有3 名玩家成功的概率问题,我在最后一种情况下得到 ~ 10.8%

编辑:根据要求,这是生成图的代码。我还修复了存在一些命名问题的各种函数(在我创建它们时使用了几个不同的名称)。看起来它导致了第三个函数的一个小错误,但我已经修复了它。

于 2021-10-15T20:45:45.193 回答
2

这是 R 中的蒙特卡洛实验,返回失败次数的分布。

apply(apply(matrix(rgeom(16*1e6,.5)+1,nc=16),1,cumsum)>18,1,mean)
#with details:
#rgeom(16*1e6,.5)+1 for 16 x 10⁶ geometric simulations when
#the outcome is the number of attempts till "success",
# "success" included
#,1,cumsum) for the number of steps till 16th "success"
#)>18 for counting the cases when a player manages to X the bridge
#1,mean) for finding the probability of each of the players to X

不是二项式,而是截断的负二项式实验,因为每个玩家迈出的新步数是 Geometric Geom(1/2) 变量,除非已经完成了 18 步。因此,平均幸存者人数为

sum(1-pnbinom(size=1:16,q=17:2,prob=.5))
#Explanation:
#pnbinom is the Negative Binomial cdf
#with size the number of "successes"
#q the integer at which the cdf is computed
#prob is the Negative Binomial probability parameter
#Because nbinom() is calibrated as the number of attempts
#before "success", rather than until "success", the value of
#q decreases by one for each player in the game

其值为 7.000076,而不是16-18/2=7!

于 2021-11-02T13:34:55.440 回答
1

如果我理解正确,我相信其他答案会使模拟复杂化。

我们可以从大小为 18 的二项分布中模拟平局。每个人都会1杀死一个人(假设还有人要杀死)。因此,我们可以通过从玩家数量中减去 1 的数量来计算幸存者的数量,截断为 0(任何负数结果都计为 0,通过pmax())。

set.seed(47)
n_sim = 1e4
survivors = pmax(0, 16 - rbinom(n_sim, size = 18, prob = 0.5))
mean(survivors)
# [1] 7.009

平均值似乎接近西安的答案,7.000076即随着n_sim增加。在 500M 模拟中(使用这种方法仍然运行得相当快!)我们得到平均值 7.000073。

绘制这些结果,它们看起来与 cazman 的squid2场景基本相同。

ggplot(data.frame(survivors), aes(x = survivors)) + geom_bar() +
  scale_y_continuous(limits = c(0, 6000))

在此处输入图像描述

于 2021-11-03T18:27:48.127 回答
0

很好地模拟这个游戏。您将需要 50%/50% 的几率 16 次。这意味着您所需要编写的代码是 50% 的机会不会输球,并且运行 16 次而不是输球,它会从 18 的变量中得到一个 -1。这将创建一个完美的 squidgame bridge 数字娱乐

于 2022-01-01T19:03:55.793 回答