鱿鱼游戏第 7 集模拟
Squid game Episode 7 with simulation
昨晚看了电视剧《鱿鱼游戏》第七集。这集在桥上有一个二项分布的游戏。
具体有16名球员和一座桥,有18副眼镜(一副纯玻璃和一副安全玻璃)。如果一个球员碰巧选择了纯玻璃,那么玻璃就无法承受球员的重量并且玻璃碎了。下一位玩家的优势是 he/she 从最后一位玩家的位置开始并继续二项式 search.At 最后 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))
好像不行。有帮助吗?
以下是我认为您可以在 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%
编辑: 根据要求,这里是生成图表的代码。我还修复了存在命名问题的各种函数(创建它们时使用了几个不同的名称)。看起来它导致了第三个函数的一个小错误,但我已经完全修复了它。
○△□
##########
# 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="○ △ □ ○ △ □ ○ △ □",
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)
这是 R 中的一个 Monte Carlo 实验,返回失败次数的分布。
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
这不是一个二项式实验,而是一个截断的负二项式实验,因为每个玩家的新步数是一个几何 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
!
如果我理解正确,我相信其他答案会使模拟复杂化。
我们可以模拟大小为 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
随着 n_sim
的增加,平均值似乎接近西安 7.000076
的答案。在 500M 模拟(使用此方法仍然运行得相当快!)时,我们得到的平均值为 7.000073。
绘制这些结果,它们看起来与 cazman 的 squid2
场景基本相同。
ggplot(data.frame(survivors), aes(x = survivors)) + geom_bar() +
scale_y_continuous(limits = c(0, 6000))
很好模拟这个游戏。你将需要 50%/50% 的机会 16 次。这意味着你所需要的代码是 50% 的机会不输,运行 它是你输了的 16 倍,它会做一个 -1 形式的变量 18。这将创造一个完美的鱿鱼游戏桥[数字娱乐] =10=]
昨晚看了电视剧《鱿鱼游戏》第七集。这集在桥上有一个二项分布的游戏。
具体有16名球员和一座桥,有18副眼镜(一副纯玻璃和一副安全玻璃)。如果一个球员碰巧选择了纯玻璃,那么玻璃就无法承受球员的重量并且玻璃碎了。下一位玩家的优势是 he/she 从最后一位玩家的位置开始并继续二项式 search.At 最后 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))
好像不行。有帮助吗?
以下是我认为您可以在 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%
编辑: 根据要求,这里是生成图表的代码。我还修复了存在命名问题的各种函数(创建它们时使用了几个不同的名称)。看起来它导致了第三个函数的一个小错误,但我已经完全修复了它。
○△□
##########
# 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="○ △ □ ○ △ □ ○ △ □",
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)
这是 R 中的一个 Monte Carlo 实验,返回失败次数的分布。
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
这不是一个二项式实验,而是一个截断的负二项式实验,因为每个玩家的新步数是一个几何 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
!
如果我理解正确,我相信其他答案会使模拟复杂化。
我们可以模拟大小为 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
随着 n_sim
的增加,平均值似乎接近西安 7.000076
的答案。在 500M 模拟(使用此方法仍然运行得相当快!)时,我们得到的平均值为 7.000073。
绘制这些结果,它们看起来与 cazman 的 squid2
场景基本相同。
ggplot(data.frame(survivors), aes(x = survivors)) + geom_bar() +
scale_y_continuous(limits = c(0, 6000))
很好模拟这个游戏。你将需要 50%/50% 的机会 16 次。这意味着你所需要的代码是 50% 的机会不输,运行 它是你输了的 16 倍,它会做一个 -1 形式的变量 18。这将创造一个完美的鱿鱼游戏桥[数字娱乐] =10=]