在 R 中模拟掷骰子

Simulating Dice Rolls in R

我正在尝试用 R 编写以下游戏代码:

我尝试如下手动模拟 - 我首先使用 R 中的“runif”命令“掷骰子”很多次,希望你最终会看到 4,然后是 6(我不知道如何使用“do until loops”对此进行编码)。我重复了 100 次并将所有这些卷放入数据框中:

roll_1 = floor(runif(100, min=1, max=6))

roll_2 = floor(runif(100, min=1, max=6))

roll_3 = floor(runif(100, min=1, max=6))

roll_4 = floor(runif(100, min=1, max=6))

roll_5 = floor(runif(100, min=1, max=6))

#etc 

roll_100 = floor(runif(100, min=1, max=6))

all_rolls = data.frame(roll_1, roll_2, roll_3, roll_4, roll_5, roll_100)

看起来如下:

head(all_rolls)
  roll_1 roll_2 roll_3 roll_4 roll_5 roll_100
1      4      2      5      3      1        4
2      3      2      4      4      1        2
3      1      3      1      4      2        1
4      3      2      1      4      4        3
5      4      1      2      2      5        5
6      2      3      3      5      3        1

然后我将此数据框导出到 Microsoft Excel 并手动检查每一列并计算前面有 4 时出现 6 的行号。然后我对所有列的这个数字取平均值并计算在观察到 4 后是 6 之前,您需要掷骰子的平均次数。这需要一些时间才能做到,但它奏效了。

我正在寻找一种更快的方法来完成这项工作。有谁知道 R 中是否可以使用“do until”循环来加速这个“游戏”?

谢谢

而不是 runif,我会 sample 1:6 值,因为骰子只有 1 到 6 的值,不会有 1.23 等值。

这就是你如何使用 while 循环 -

roll_from_4_to6 <- function() {
  n <- 1:6
  i <- 1
  previous_4 <- FALSE
  while(TRUE) {
    current_value = sample(n, 1)
    i <- i + 1
    if(previous_4 && current_value == 6) break
    previous_4 <- current_value == 4
  }
  i
}

运行一次。

roll_from_4_to6()

运行100次取平均值

mean(replicate(100, roll_from_4_to6()))

从骰子中抽样遵循分类分布。通过使用 extraDistr 包中的 rcat 函数,您可以从分类分布中抽样

roll_game <- function() {
  count <- 2
  dices <- rcat(2, c(1/6 ,1/6, 1/6, 1/6, 1/6, 1/6))
  while(!(rev(dices)[2] ==4 && rev(dices)[1] ==6 )){
    dices <- c(dices, rcat(1, c(1/6 ,1/6, 1/6, 1/6, 1/6, 1/6)))
    count <- count+1
  }
  count
}

mean(replicate(100, roll_game()))

会得到你的答案

我考虑了一种不同的方法来解决这个问题,与您收到的确切说明不同。

创建一个非常大的滚动序列,这样您就可以找到 100 个 6 跟随 4 的情况:

x = sample(1:6, 1e6, TRUE)

在 4 之后获得 6 所需的滚动平均值是:

mean(diff(which(x == 4 & data.table::shift(x) == 6)[1:100]))

你在那里做什么:

  • x == 4 & data.table::shift(x) == 6 是一个记录向量,4 后跟一个 6。这个向量是一堆 FALSE 和 TRUE。
  • which(x == 4 & data.table::shift(x) == 6)[1:100]是那些TRUE的索引(前100个TRUE)
  • diff 告诉我们连续比赛之间有多少次掷骰。
  • mean 给出最后一个值的平均值。