JavaScript模拟蒙提霍尔问题异常:切换与不切换胜率均为33%求助
蒙提霍尔问题模拟代码错误排查与修正
主要错误点
- 初始选择未每次重置:原代码中
choices变量在循环外定义,导致所有试验共用同一个初始门选择,完全违背了每次试验独立选择的核心逻辑。 - 赋值运算符错误:
realDoor == 1分支里误用fakeDoor == ...(比较运算符)而非fakeDoor = ...(赋值运算符),导致fakeDoor未被正确初始化。 - 数组删除方法误用:
array.pop(choice - 1)是错误用法,pop()不接受参数,只会删除数组最后一个元素。删除指定索引元素应使用splice(index, 1)。 - 冗余变量:
truth变量定义后从未使用,属于无效代码。
修正后的代码
function overAndOver(shouldSwitch, numTrials) { let wins = 0; let losses = 0; for(let i = 0; i < numTrials; i++) { // 每次试验重新生成初始选择 const initialChoice = 1 + Math.floor(Math.random() * 3); const result = runMontyHallTrial(initialChoice, shouldSwitch); result ? wins++ : losses++; } const winRate = (wins / numTrials).toFixed(4); console.log(`获胜次数:${wins}`); console.log(`失败次数:${losses}`); console.log(`总试验次数:${numTrials}`); console.log(`胜率:${winRate}`); } function runMontyHallTrial(initialChoice, shouldSwitch) { const realDoor = 1 + Math.floor(Math.random() * 3); const allDoors = [1, 2, 3]; // 主持人选择打开一扇非真实、非初始选择的门 const availableFakeDoors = allDoors.filter(door => door !== realDoor && door !== initialChoice); const openedFakeDoor = availableFakeDoors[Math.floor(Math.random() * availableFakeDoors.length)]; let finalChoice = initialChoice; if (shouldSwitch) { // 切换选择:取既不是初始选择也不是已打开门的剩余门 finalChoice = allDoors.find(door => door !== initialChoice && door !== openedFakeDoor); } return finalChoice === realDoor ? 1 : 0; } // 测试10000次,样本量足够看到真实胜率 overAndOver(true, 10000); console.log(""); overAndOver(false, 10000);
修正逻辑说明
- 每次试验独立生成初始选择,符合蒙提霍尔问题的场景设定。
- 主持人开门逻辑简化为过滤+随机选择,避免原代码复杂分支的潜在错误。
- 切换选择逻辑直接通过查找剩余有效门实现,清晰易懂。
- 使用更现代的JS语法优化代码可读性,同时保证逻辑准确性。
内容的提问来源于stack exchange,提问作者killLakill89
相关产品推荐
相关产品推荐

