在 R 中模拟掷骰子
Simulating Dice Rolls in R
我正在尝试用 R 编写以下游戏代码:
- 掷骰子,直到观察到 4 后跟 6
- 数一数您观察到 4 后跟 6 的次数
- 重复前两个步骤 100 次
- 计算观察到 4 后跟 6 的平均次数
我尝试如下手动模拟 - 我首先使用 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
给出最后一个值的平均值。
我正在尝试用 R 编写以下游戏代码:
- 掷骰子,直到观察到 4 后跟 6
- 数一数您观察到 4 后跟 6 的次数
- 重复前两个步骤 100 次
- 计算观察到 4 后跟 6 的平均次数
我尝试如下手动模拟 - 我首先使用 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
给出最后一个值的平均值。