如何在 r 中针对 "gambling" 问题和 return 概率编写模拟?
How do I write a simulation in r for a "gambling" problem and return probability?
我正在尝试 运行 在 R 中进行模拟,但我不确定从哪里开始。问题如下:
"You have 0 and are making bets on a fair game. What is the probability that you will have lost all your money by the time you have placed your 100th bet?"
到目前为止,我已经编写了一个小函数来从 "coin flip" 生成随机结果,但这就是我所获得的。
win.lose <- function(x){
sample(0:1, x, rep=TRUE)
}
我担心的是这个功能不考虑从奖金中赚钱。在这里为上述问题编写更好的函数的一些帮助将不胜感激。谢谢!
您可以像这样模拟 100 次投注。
library(dplyr)
current_balance <- 100
bet <- 10
odds <- 0.5
for(i in 1:100) {
current_balance <- current_balance - bet # place bet
outcome <- ifelse(runif(1) > 0.5,
bet * 2, # win: receive twice the bet ()
0) # lose and the initial is lost
current_balance <- current_balance + outcome
paste("Balance after", i, "bets is:", current_balance) %>% print
if(current_balance <= 0) { stop() }
}
您可以将整个过程包装在另一个循环中多次 运行 模拟,并记录结果,就像这样
ending_balances <- c()
for(s in 1:10) {
current_balance <- 100
bet <- 10
odds <- 0.5
for(i in 1:100) {
current_balance <- current_balance - bet # place bet
outcome <- ifelse(runif(1) > 0.5,
bet * 2, # win: receive twice the bet ()
0) # lose and the initial is lost
current_balance <- current_balance + outcome
# paste("Balance after", i, "bets is:", current_balance) %>% print
if(current_balance <= 0) {
ending_balances[s] <- current_balance
break()
}
ending_balances[s] <- current_balance
}
}
> ending_balances
[1] 0 80 220 60 0 120 0 80 0 200
既然你有100,你就用10,那你就只有90了。这里的技巧是,如果你赢了,你的收益是多少。如果加倍,则需要sample(c(-1,2), 100, rep=TRUE)
.
win.lose <- function(){
total <- 90
for(i in c(1:100)){
bet_output <- sample(c(-1,2), 1, rep=TRUE)
total <- total + 10 * bet_output
if(total<0) return(total)
}
return(total)
}
sim_y <- unlist(lapply(c(1:10000), function(i){win.lose()} ))
sum(sim_y < 0)/length(sim_y)
我们可以编写一个函数来 sample
-10(输)和 20(赢)100 次并且 return TRUE
如果在 100 次投注中的任何时候我们输掉所有的钱( 100 美元)。
lost.balance <- function() {
total <- cumsum(sample(c(-10, 20), 100, replace = TRUE))
any(total <= -100)
}
我们可以用replicate
n
次模拟,用table
计算比例
n <- 10000
table(replicate(n, lost.balance()))/n
# FALSE TRUE
# 0.9902 0.0098
这是 binomial
分布的一个简单问题。
- 第一:由于我们有兴趣计算概率“当您下第 100 个赌注”时,我们需要计算在第 100 次试验之前我们最多可以成功多少次才能 运行 没钱:
需要求解的方程式是:
100 + 20*X + (99 - X)*(-10) <= 0
,其中X
是在99次试验中应达到的成功的必要次数。这只会导致 36
成功。
第二个:因为我们已经知道我们需要 36
次成功 99
次投注,我们可以使用 pbinom
函数来计算获得 36
或更少 成功的概率 如果我们赌博 99 次:
pbinom(36,99,0.5)
这导致 0.004316793
的概率。
这是公平游戏的通用框架,可用于任何数量的初始财富、投注金和终止试验。
注意: 顺便说一句,与任何模拟方法相比,这计算出准确的概率!
r 使用矢量化效果最好。我们应该一次全部采样,而不是循环:
sample(c(-1, 1), 100, replace = TRUE)
我们还知道,如果净亏损 10 次,我们就会破产。转换为累计总和:
cumsum(sample(c(-1, 1), 100, replace = TRUE))
any(cumsum(sample(c(-1, 1), 100, replace = TRUE)) == -10)
最后,我们可以使用 replicate()
重复这个完全相同的模拟:
#specify simulation criteria
n <- 100
n_sim <- 10
# betting criteria
n_broke <- 10 #if we have 10 net losses, we're broke
bet <- 10 #each bet is
# way 1
set.seed(123)
replicate(n_sim, cumsum(sample(c(-1, 1), n, replace = TRUE)))
#or with actual money totals - note, 1st row is the initial money amount
set.seed(123)
replicate(n_sim, cumsum(c(n_broke * bet, bet * sample(c(-1, 1), n, replace = TRUE))))
#or a summary of it:
set.seed(123)
table(replicate(n_sim, ifelse(any(cumsum(sample(c(-1, 1), n, replace = TRUE)) == -n_broke), 'Out_of_Money', 'Has_Money')))
#faster way to do it:
set.seed(123)
table(
ifelse(
apply(matrix(sample(c(-1,1), n * n_sim, replace = TRUE), ncol = n_sim),
2,
function(x) min(cumsum(x)) <= -n_broke),
'Out_of_Money', 'Has_Money')
)
对于 n_sim = 10,000:
Has_Money Out_of_Money
6783 3217
以及幕后发生的事情:
set.seed(123)
replicate(n_sim, cumsum(c(n_broke * bet, bet * sample(c(-1, 1), n, replace = TRUE))))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 100 100 100 100 100 100 100 100 100 100
[2,] 90 90 110 110 90 110 110 110 90 110
[3,] 80 100 120 120 80 120 120 100 80 120
[4,] 70 110 130 110 70 130 130 90 90 110
[5,] 80 100 120 120 60 140 120 80 100 100
[6,] 70 110 130 110 50 130 110 90 90 110
[7,] 80 120 140 100 40 120 100 80 80 120
[8,] 90 110 150 110 50 110 90 70 70 130
[9,] 100 100 140 100 40 100 100 60 60 120
我正在尝试 运行 在 R 中进行模拟,但我不确定从哪里开始。问题如下:
"You have 0 and are making bets on a fair game. What is the probability that you will have lost all your money by the time you have placed your 100th bet?"
到目前为止,我已经编写了一个小函数来从 "coin flip" 生成随机结果,但这就是我所获得的。
win.lose <- function(x){
sample(0:1, x, rep=TRUE)
}
我担心的是这个功能不考虑从奖金中赚钱。在这里为上述问题编写更好的函数的一些帮助将不胜感激。谢谢!
您可以像这样模拟 100 次投注。
library(dplyr)
current_balance <- 100
bet <- 10
odds <- 0.5
for(i in 1:100) {
current_balance <- current_balance - bet # place bet
outcome <- ifelse(runif(1) > 0.5,
bet * 2, # win: receive twice the bet ()
0) # lose and the initial is lost
current_balance <- current_balance + outcome
paste("Balance after", i, "bets is:", current_balance) %>% print
if(current_balance <= 0) { stop() }
}
您可以将整个过程包装在另一个循环中多次 运行 模拟,并记录结果,就像这样
ending_balances <- c()
for(s in 1:10) {
current_balance <- 100
bet <- 10
odds <- 0.5
for(i in 1:100) {
current_balance <- current_balance - bet # place bet
outcome <- ifelse(runif(1) > 0.5,
bet * 2, # win: receive twice the bet ()
0) # lose and the initial is lost
current_balance <- current_balance + outcome
# paste("Balance after", i, "bets is:", current_balance) %>% print
if(current_balance <= 0) {
ending_balances[s] <- current_balance
break()
}
ending_balances[s] <- current_balance
}
}
> ending_balances
[1] 0 80 220 60 0 120 0 80 0 200
既然你有100,你就用10,那你就只有90了。这里的技巧是,如果你赢了,你的收益是多少。如果加倍,则需要sample(c(-1,2), 100, rep=TRUE)
.
win.lose <- function(){
total <- 90
for(i in c(1:100)){
bet_output <- sample(c(-1,2), 1, rep=TRUE)
total <- total + 10 * bet_output
if(total<0) return(total)
}
return(total)
}
sim_y <- unlist(lapply(c(1:10000), function(i){win.lose()} ))
sum(sim_y < 0)/length(sim_y)
我们可以编写一个函数来 sample
-10(输)和 20(赢)100 次并且 return TRUE
如果在 100 次投注中的任何时候我们输掉所有的钱( 100 美元)。
lost.balance <- function() {
total <- cumsum(sample(c(-10, 20), 100, replace = TRUE))
any(total <= -100)
}
我们可以用replicate
n
次模拟,用table
n <- 10000
table(replicate(n, lost.balance()))/n
# FALSE TRUE
# 0.9902 0.0098
这是 binomial
分布的一个简单问题。
- 第一:由于我们有兴趣计算概率“当您下第 100 个赌注”时,我们需要计算在第 100 次试验之前我们最多可以成功多少次才能 运行 没钱:
需要求解的方程式是:
100 + 20*X + (99 - X)*(-10) <= 0
,其中X
是在99次试验中应达到的成功的必要次数。这只会导致36
成功。 第二个:因为我们已经知道我们需要
36
次成功99
次投注,我们可以使用pbinom
函数来计算获得36
或更少 成功的概率 如果我们赌博 99 次:pbinom(36,99,0.5)
这导致 0.004316793
的概率。
这是公平游戏的通用框架,可用于任何数量的初始财富、投注金和终止试验。
注意: 顺便说一句,与任何模拟方法相比,这计算出准确的概率!
r 使用矢量化效果最好。我们应该一次全部采样,而不是循环:
sample(c(-1, 1), 100, replace = TRUE)
我们还知道,如果净亏损 10 次,我们就会破产。转换为累计总和:
cumsum(sample(c(-1, 1), 100, replace = TRUE))
any(cumsum(sample(c(-1, 1), 100, replace = TRUE)) == -10)
最后,我们可以使用 replicate()
重复这个完全相同的模拟:
#specify simulation criteria
n <- 100
n_sim <- 10
# betting criteria
n_broke <- 10 #if we have 10 net losses, we're broke
bet <- 10 #each bet is
# way 1
set.seed(123)
replicate(n_sim, cumsum(sample(c(-1, 1), n, replace = TRUE)))
#or with actual money totals - note, 1st row is the initial money amount
set.seed(123)
replicate(n_sim, cumsum(c(n_broke * bet, bet * sample(c(-1, 1), n, replace = TRUE))))
#or a summary of it:
set.seed(123)
table(replicate(n_sim, ifelse(any(cumsum(sample(c(-1, 1), n, replace = TRUE)) == -n_broke), 'Out_of_Money', 'Has_Money')))
#faster way to do it:
set.seed(123)
table(
ifelse(
apply(matrix(sample(c(-1,1), n * n_sim, replace = TRUE), ncol = n_sim),
2,
function(x) min(cumsum(x)) <= -n_broke),
'Out_of_Money', 'Has_Money')
)
对于 n_sim = 10,000:
Has_Money Out_of_Money
6783 3217
以及幕后发生的事情:
set.seed(123)
replicate(n_sim, cumsum(c(n_broke * bet, bet * sample(c(-1, 1), n, replace = TRUE))))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 100 100 100 100 100 100 100 100 100 100
[2,] 90 90 110 110 90 110 110 110 90 110
[3,] 80 100 120 120 80 120 120 100 80 120
[4,] 70 110 130 110 70 130 130 90 90 110
[5,] 80 100 120 120 60 140 120 80 100 100
[6,] 70 110 130 110 50 130 110 90 90 110
[7,] 80 120 140 100 40 120 100 80 80 120
[8,] 90 110 150 110 50 110 90 70 70 130
[9,] 100 100 140 100 40 100 100 60 60 120