实证骰子分布时,用累计总和替代数组优化均值计算程序的可行性
问题解答
核心结论
用累计总和替代数组来计算均值完全可行,还能大幅节省内存——只需要维护一个累加变量,不用存储上千个样本值。但要注意:这种方法只能验证均值是否符合期望值,没法直接用来验证分布类型(比如1d12的均匀性、2d6的正态性)。
具体分析
- 均值计算层面:先存数组再求和取平均,和边生成样本边累加最后除以样本数,数学结果完全一致。你给出的示例代码就是这个逻辑,没有问题。比如1d12的期望值是6.5,2d6的期望值是7,样本量足够大时,累加得到的均值会无限接近这些数值。
- 分布验证层面:要证明1d12是均匀分布,得统计1-12每个点数的出现频率是否相近;要证明2d6是正态分布,得统计2-12每个和值的出现次数是否符合钟形曲线。这些都需要记录每个结果的出现次数,光靠累加总和做不到,得额外维护计数变量(比如长度为12的数组存1d12各点数次数,长度为11的数组存2d6各和值次数),但就算这样,内存消耗也比存1000个样本小得多。
优化代码思路(以2d6为例)
如果既要验证分布又想省内存,不用存所有样本,只维护计数数组即可:
// 初始化计数数组,索引对应2d6的和值(2-12),初始值为0 let count = new Array(11).fill(0); const totalSamples = 1000; for (let i = 0; i < totalSamples; i++) { let dice1 = Math.floor(Math.random() * 6) + 1; let dice2 = Math.floor(Math.random() * 6) + 1; let sum = dice1 + dice2; count[sum - 2]++; // 和值2对应索引0,以此类推 } // 基于计数数组计算均值 let runningTotal = 0; for (let i = 0; i < count.length; i++) { runningTotal += (i + 2) * count[i]; } let mean = runningTotal / totalSamples; // 输出各和值频率,验证正态分布特征 for (let i = 0; i < count.length; i++) { console.log(`和值${i+2}:${(count[i]/totalSamples*100).toFixed(2)}%`); } console.log(`均值:${mean.toFixed(2)}`);
内容的提问来源于stack exchange,提问作者sweng
相关产品推荐
相关产品推荐

