在R语言中计算10枚骰子总和的区间概率方法
在R语言中计算10枚骰子总和的区间概率方法
嘿,你的基础代码已经找对方向啦!现在咱们把单个总和的概率汇总到你需要的区间里,其实很简单,跟着下面的步骤来就行:
首先,先回顾下你当前的代码逻辑:你已经生成了10枚骰子所有可能的组合(总共6^10种),算出了每个组合的总和,接着通过循环得到了每个可能总和(10到60)的概率。现在要做的就是把这些总和按你指定的区间(10-20、20-30……50-60)分组,再把每个区间内的概率加总起来。
步骤1:定义区间规则
首先咱们得明确区间的划分方式,比如20这个值是属于前一个区间还是后一个?这里推荐用R的cut()函数来处理,它能帮咱们快速把数值分到对应的区间里:
# 定义区间的分割点:从10开始,每次加10直到60 breaks <- seq(10, 60, by = 10) # 把每个总和分到对应的区间中 # include.lowest=TRUE 确保10被包含在第一个区间里 # right=FALSE 表示区间是左闭右开,比如[10,20)、[20,30)...最后一个区间是[50,60](因为60是最大值) sum_intervals <- cut(dice.sums, breaks = breaks, include.lowest = TRUE, right = FALSE)
步骤2:计算区间概率
这里有两种高效的方法,你可以任选一种:
方法一:基于你已有的单个总和概率计算
如果你想保留之前算出的all_prob,可以把总和和概率做成数据框,再按区间分组求和:
# 把总和和对应的概率整理成数据框 sum_prob_df <- data.frame(sum = 10:60, prob = all_prob) # 给每个总和分配区间 sum_prob_df$interval <- cut(sum_prob_df$sum, breaks = breaks, include.lowest = TRUE, right = FALSE) # 按区间分组,把区间内的概率加起来 interval_prob <- tapply(sum_prob_df$prob, sum_prob_df$interval, sum) # 输出结果 print(interval_prob)
方法二:直接从总和数据计算(更高效)
其实不用先算单个总和的概率,直接从dice.sums里统计每个区间的组合数占总组合数的比例就行(毕竟每个组合的概率都是1/6^10):
# 按区间分组,计算区间内的组合数除以总组合数,得到概率 interval_prob <- tapply(dice.sums, sum_intervals, function(x) length(x)/nrow(dice)) print(interval_prob)
优化你原来的循环代码
另外,你原来的循环可以用更简洁的R风格写法替代,效率也更高:
# 替代原来的for循环,快速计算每个总和的概率 all_prob <- sapply(10:60, function(s) mean(dice.sums == s))
完整示例代码
把所有步骤整合起来的完整代码如下:
K <- 10 all_comb <- rep(list(1:6), K) dice <- expand.grid(all_comb) dice.sums <- rowSums(dice) # 定义区间分割点 breaks <- seq(10, 60, by = 10) # 方法一:基于单个总和概率计算区间概率 all_prob <- sapply(10:60, function(s) mean(dice.sums == s)) sum_prob_df <- data.frame(sum = 10:60, prob = all_prob) sum_prob_df$interval <- cut(sum_prob_df$sum, breaks = breaks, include.lowest = TRUE, right = FALSE) interval_prob1 <- tapply(sum_prob_df$prob, sum_prob_df$interval, sum) # 方法二:直接从总和计算区间概率 sum_intervals <- cut(dice.sums, breaks = breaks, include.lowest = TRUE, right = FALSE) interval_prob2 <- tapply(dice.sums, sum_intervals, function(x) length(x)/nrow(dice)) # 查看结果(两种方法结果完全一致) print(interval_prob1) print(interval_prob2)
如果需要调整区间的归属规则(比如改成右闭左开),只需要修改cut()函数里的right参数就行,确保区间互斥且覆盖所有可能的总和就好~
备注:内容来源于stack exchange,提问作者Keith Duong
相关产品推荐
相关产品推荐

