用蒙特卡洛法求解三门问题和Π

一、三门问题

三门问题是一个经典的概率谜题:假设你参加一个游戏,有三扇关闭的门,其中一扇门后有汽车(中奖),另外两扇门后是山羊(不中奖)。规则如下:

  1. 你先随机选择一扇门(例如门 1)。

  2. 主持人知道哪扇门后有汽车,且一定会打开另一扇有山羊的门(例如打开门 2)。

  3. 此时你可以选择保持最初的选择,或切换到剩下的那扇未打开的门(例如门 3)。

问题:哪种策略(保持不变 / 切换选择)的中奖概率更高?

二、思路

  1. 模拟游戏过程:随机设定汽车所在的门、玩家初始选择、主持人打开的门。

  2. 两种策略对比

  • 策略 1:不换门,坚持最初的选择。

  • 策略 2:换门,选择主持人未打开的另一扇门。

  1. 重复试验:通过大量模拟(如 100 万次),计算两种策略的中奖概率。

三、Python 实现代码

import numpy as np

# 设置试验次数(越大结果越稳定)
n_trials = 1000000

# 初始化两种策略的中奖次数
stick_wins = 0  # 不换门中奖次数
switch_wins = 0  # 换门中奖次数

for _ in range(n_trials):
    # 1. 随机设定汽车所在的门(0,1,2分别代表三扇门)
    car_door = np.random.randint(0, 3)
    
    # 2. 玩家随机选择一扇门
    player_choice = np.random.randint(0, 3)
    
    # 3. 主持人打开一扇有山羊的门(既不是汽车门,也不是玩家选择的门)
    # 找出所有可能打开的门(排除汽车门和玩家选择的门)
    possible_doors = [door for door in [0,1,2] if door != car_door and door != player_choice]
    # 主持人随机打开其中一扇(当玩家选错时只有1种可能,选对时有2种可能)
    host_opens = np.random.choice(possible_doors)
    
    # 4. 计算两种策略的中奖情况
    # 策略1:不换门
    if player_choice == car_door:
        stick_wins += 1
    
    # 策略2:换门(选择剩下的未打开的门)
    switched_choice = [door for door in [0,1,2] if door != player_choice and door != host_opens][0]
    if switched_choice == car_door:
        switch_wins += 1

# 计算概率
stick_prob = stick_wins / n_trials
switch_prob = switch_wins / n_trials

print(f"试验次数:{n_trials}")
print(f"不换门中奖概率:{stick_prob:.4f}(约1/3)")
print(f"换门中奖概率:{switch_prob:.4f}(约2/3)")
试验次数:1000000

不换门中奖概率:0.3335(约1/3)

换门中奖概率:0.6665(约2/3)

数学结论:

  1. 初始选择正确的概率为 1/3,此时换门会失败。

  2. 初始选择错误的概率为 2/3,此时主持人打开另一扇错误的门后,换门一定能选中汽车,因此换门成功的概率为 2/3。

Π

import numpy as np
import matplotlib.pyplot as plt

# 1. 设置参数
n_points = 100000  # 随机点数量(数量越多,结果越精确)

# 2. 生成随机点(x和y的范围均为[-1,1])
x = np.random.uniform(-1, 1, n_points)  # 生成n_points个[-1,1)之间的随机数
y = np.random.uniform(-1, 1, n_points)

# 3. 判断点是否落在单位圆内(x² + y² ≤ 1)
inside_circle = (x**2 + y**2) <= 1
m = np.sum(inside_circle)  # 落在圆内的点数

# 4. 计算Π的近似值
pi_approx = 4 * m / n_points
print(f"随机点数量:{n_points}")
print(f"落在圆内的点数:{m}")
print(f"Π的近似值:{pi_approx}")

# 5. 可视化结果
plt.figure(figsize=(6, 6))  # 创建正方形画布
# 绘制落在圆内的点(蓝色)和圆外的点(红色)
plt.scatter(x[inside_circle], y[inside_circle], c='blue', s=1, alpha=0.5, label='圆内点')
plt.scatter(x[~inside_circle], y[~inside_circle], c='red', s=1, alpha=0.5, label='圆外点')
plt.xlim(-1, 1)
plt.ylim(-1, 1)
plt.axis('equal')  # 保证x和y轴比例一致
plt.title(f'蒙特卡洛法求Π(近似值:{pi_approx:.4f})')
plt.legend()
plt.show()
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值