py-test/simulate_monty_hall.py

66 lines
2.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import random
def simulate_monty_hall(switch, num_trials=100000):
"""
模拟三门悖论(蒙提霍尔问题)
参数:
- switch: bool, 是否在主持人打开门后选择换门
- num_trials: int, 模拟次数默认10万次
返回:
- 获胜次数
- 胜率
"""
win_count = 0
doors = [1, 2, 3] # 三扇门
for _ in range(num_trials):
# 随机放置汽车1 表示汽车0 表示山羊)
car_door = random.choice(doors)
# 参赛者初始选择
player_choice = random.choice(doors)
# 主持人要打开一扇门:不能是参赛者选的,也不能是有车的
remaining_doors = [d for d in doors if d != player_choice and d != car_door]
host_opens = random.choice(remaining_doors)
# 换门逻辑
if switch:
# 换到剩下的那一扇未被选、未被开的门
final_choice = [d for d in doors if d != player_choice and d != host_opens][0]
else:
# 不换,保持原选择
final_choice = player_choice
# 判断是否获胜
if final_choice == car_door:
win_count += 1
win_rate = win_count / num_trials
return win_count, win_rate
# === 运行模拟 ===
if __name__ == "__main__":
num_trials = 100000
print(f"模拟 {num_trials} 次三门问题:\n")
# 情况1坚持不换门
wins_stay, rate_stay = simulate_monty_hall(switch=False, num_trials=num_trials)
print(f"坚持原选择(不换门):")
print(f" 获胜次数: {wins_stay}")
print(f" 胜率: {rate_stay:.4f} ({rate_stay * 100:.2f}%)\n")
# 情况2总是换门
wins_switch, rate_switch = simulate_monty_hall(switch=True, num_trials=num_trials)
print(f"总是换门:")
print(f" 获胜次数: {wins_switch}")
print(f" 胜率: {rate_switch:.4f} ({rate_switch * 100:.2f}%)\n")
print("理论值对比:")
print(" 不换门胜率: 1/3 ≈ 33.33%")
print(" 换门胜率: 2/3 ≈ 66.67%")