首页 > 解决方案 > R - 一个数字在多个可变数量的模具上的概率

问题描述

我正在尝试编写一个 r 脚本,用于在至少一个骰子上滚动骰子上的最高数字(在本例中为 6),以累积一组骰子(1、2、3、4、5、6 骰子)任意骰子(在本例中为 d6;代码应该很容易调整到其他骰子,如 d8 d10 d12)。我正在寻找的结果对于 d6 大致是这样的:

骰子 (p) 所有 6s 1 0.16667 2 0.2334 3 0.2927 ...

z <- 1
b <- c(numeric)
while(z < 6) {
  b[z] <- sapply(1:1, function(z) mean(rbinom(10000, z, 1/6) > 0))
  z <- z + 1
}
b

我最终得到了这个:

[1] 0.1631 0.1637 0.1716 0.1623 0.1659 0.1648

我无法让 while 循环正确执行。有什么建议么?

标签: rmontecarlodice

解决方案


我认为您想要的是一种系统地模拟骰子滚动次数越来越多的方法。让我们尝试一个基于 的函数sample

dice <- function(sides, times){
  sample(1:sides, times, replace = TRUE)
}

如果你想掷 2d6,那么你做

set.seed(9) # for reproducibility
dice(6, 2)  
[1] 3 5

假设您想从 1 到 6 d6s 重复此操作。现在我们需要sapply. 您将获得一个包含所有输出的列表。

set.seed(9)
sapply(1:6, function(z) dice(6, z))

[[1]]
[1] 3

[[2]]
[1] 5 6

[[3]]
[1] 3 3 3

[[4]]
[1] 4 3 6 4

[[5]]
[1] 5 2 5 2 4

[[6]]
[1] 3 4 6 1 6 1

现在您要检查它们是否都等于某个其他值(例如 6)。您可以比较您的输出并使用all.

set.seed(9)
all(dice(6, 2) == 6)
[1] FALSE

将此与 结合起来sapply,您将获得每个投掷次数的向量。

sapply(1:6, function(z) all(dice(6, z) == 6))
[1] FALSE FALSE FALSE FALSE FALSE FALSE

但是,您想多次重复此操作并估计 的数量概率TRUE。使用sapplyinsidesapply返回一个矩阵,我们可以转换为 data.frame 并对dplyr它执行一些操作。

library(dplyr)
set.seed(9)
sapply(1:1000, function(i) sapply(1:6, function(z) all(dice(6, z) == 6))) %>% 
  t %>% data.frame %>% 
  summarise(across(everything(), mean))
     X1    X2    X3    X4 X5 X6
1 0.156 0.017 0.005 0.002  0  0

如果您想将其包含在一个函数中,以便您可以选择边数、滚动数、目标数和重复次数,您可以。

my_fun <- function(sides, times, target, reps, seed = NULL) {
  set.seed = seed
  sapply(1:reps, function(i) sapply(1:times, function(z) all(dice(sides, z) == target))) %>% 
    t %>% data.frame %>% 
    summarise(across(everything(), mean))
}
my_fun(8, 20, 2, 100000) 

       X1      X2      X3      X4    X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20
1 0.12556 0.01551 0.00194 0.00023 1e-05  0  0  0  0   0   0   0   0   0   0   0   0   0   0   0

但是,如果没有您提供的更多信息(例如生成序列的数学公式),我无法重现您想要的输出。你说你想要的概率不会随着骰子数量的增加而增加。

它们也很容易由 的序列生成1/(sides^n)


推荐阅读