掷N个骰子区间和概率的Python实现问询(含Monte Carlo模拟尝试)
解决3个骰子点数和区间概率计算的问题
我来帮你梳理代码里的问题,然后给出正确的实现方案~
你的代码里存在的几个关键问题:
- 遗漏第三个骰子的点数:计算
roll_sum时只加了前两个骰子,导致所有和的计算完全错误。 - 计数列表的长度与索引映射错误:3个骰子的点数和范围是3到18(最小1+1+1=3,最大6+6+6=18),需要长度为16的列表来容纳所有可能的和,而不是12;同时原代码用
roll_sum-1作为索引,会导致和为3时索引为2,和为18时直接越界,完全不符合实际映射关系。 - 目标区间的索引对应错误:题目要求的区间是
3N/2 < sum <9N/2,代入N=3得到4.5 < sum <13.5,对应整数和的范围是5到13,但原代码的索引切片完全基于错误的两个骰子和的逻辑,自然得不到正确结果。
修正后的完整代码
import random # 建议增大试验次数,次数越多试验结果越接近理论概率 num_throws = 10000 # 3个骰子的和范围是3-18,共16种可能,初始化计数列表 roll_log = [0] * 16 # 根据题目公式计算区间:3*3/2=4.5,9*3/2=13.5 → 对应整数和为5到13 lower_sum = 5 upper_sum = 13 for _ in range(num_throws): # 掷3个骰子 d1 = random.randint(1, 6) d2 = random.randint(1, 6) d3 = random.randint(1, 6) total = d1 + d2 + d3 # 映射索引:sum=3 → 0,sum=4→1,...,sum=18→15,所以用total-3 roll_log[total - 3] += 1 # 打印所有点数和的试验概率,方便验证 print("各点数和的试验概率:") for idx, count in enumerate(roll_log): sum_val = idx + 3 prob = count / num_throws print(f"点数和{sum_val}: {count}/{num_throws} = {prob:.4f}") # 计算目标区间的概率:sum从5到13,对应的索引是5-3=2到13-3=10(包含两端) target_counts = sum(roll_log[2:11]) # range左闭右开,所以到11 target_prob = target_counts / num_throws print(f"\n点数和满足4.5 < sum <13.5的试验概率:{target_counts}/{num_throws} = {target_prob:.4f}")
关键修正点说明:
- 正确计算三个骰子的和:补上第三个骰子的点数,确保
total是三个骰子的真实总和。 - 正确的索引映射:用
total - 3将和的范围3-18映射到列表索引0-15,避免越界且一一对应。 - 准确的区间范围:将公式得出的浮点区间转化为整数和的范围5-13,再对应到正确的列表索引进行求和。
- 增加试验次数:原代码的20次试验结果波动极大,增大到10000次后,试验概率会更接近理论值(3个骰子该区间的理论概率为177/216≈0.8194)。
内容的提问来源于stack exchange,提问作者bicanul123
相关产品推荐
相关产品推荐

