使用JavaScript计算不放回抽取时n次连续抽到指定类型弹珠的概率
核心计算公式
不放回场景下,单种弹珠连续抽取k次的概率可以用下降阶乘的比值计算:
对于总量为m的指定类型弹珠,总弹珠数为N,连续k次抽到该类弹珠的概率为:
P(k) = [m × (m-1) × ... × (m-k+1)] / [N × (N-1) × ... × (N-k+1)]
需要注意k的取值上限为该类弹珠的总数m,超过m时概率为0,无需计算。
实现代码
你可以基于原有有放回的代码逻辑调整,每次迭代累积概率即可,不需要重复计算整段乘积:
let withoutReplacementArray = [] const total = marbles.reduce((prev, cur) => prev + cur.amount, 0) marbles.forEach(cur => { const maxDraw = cur.amount // 最多连续抽该类弹珠的次数 let currentProb = 1 // 累积概率 for(let i = 1; i <= maxDraw; i++) { // 每次迭代乘上当前第i次抽取的概率 currentProb *= (cur.amount - i + 1) / (total - i + 1) withoutReplacementArray.push({ probability: currentProb, n: i, text: cur.text }) } })
逻辑说明
- 每次循环只在上一次的概率基础上乘本次抽取的概率,避免重复计算连乘项,性能更高
- 自动限制了最大连续抽取次数为对应颜色弹珠的总量,不会出现无效计算
- 结果和你给出的示例完全匹配:比如粉色弹珠m=8,N=30,i=3时的计算就是
8/30 *7/29 *6/28,和示例完全一致
内容的提问来源于stack exchange,提问作者Lovely
相关产品推荐
相关产品推荐

