如何在 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)
}

我们可以用replicaten次模拟,用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 的概率。

这是公平游戏的通用框架,可用于任何数量的初始财富、投注金和终止试验。

注意: 顺便说一句,与任何模拟方法相比,这计算出准确的概率!

使用矢量化效果最好。我们应该一次全部采样,而不是循环:

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