66 lines
2.0 KiB
Python
66 lines
2.0 KiB
Python
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%") |