一、前言
蒙特卡罗方法(Monte Carlo Method,统计模拟法),核心思想就是大量随机投点,用频率近似概率。 本次作业我们不用复杂库封装,纯 Python 手搓,生成随机点图形,同时估算 π 的值,直观理解大数定律。适合 Python 入门、数值计算课程作业。
二、原理讲解
我们在一个边长为 2 的正方形内(范围 x∈[-1,1], y∈[-1,1]),内切一个半径为 1 的单位圆。
- 正方形面积 \(S_{square}=2\times2=4\)
- 单位圆面积 \(S_{circle}=\pi r^2=\pi\)
随机往正方形里抛大量点: 点落在圆内的概率 = 圆面积 ÷ 正方形面积 = \(\pi/4\)
\(\pi \approx 4 \times \frac{圆内点数量}{总投点数量}\)
投点越多,估算出来的 π 越接近真实值,图形上也能直观看到:蓝色点落在圆内,红色点落在圆外。
三、环境准备
需要安装绘图库 matplotlib:
pip install matplotlib四、完整 Python 代码
import random import matplotlib.pyplot as plt from matplotlib.patches import Circle # ---------------------- 蒙特卡罗参数设置 ---------------------- total_points = 15000 # 总投点数量,可以修改,越大精度越高 in_circle = 0 # 记录落在圆内的点 x_in, y_in = [], [] # 圆内点坐标 x_out, y_out = [] # 圆外点坐标 # ---------------------- 随机投点模拟 ---------------------- for _ in range(total_points): # 在[-1,1]区间生成随机x,y x = random.uniform(-1, 1) y = random.uniform(-1, 1) # 判断点是否在单位圆内:x²+y² <=1 if x**2 + y**2 <= 1: in_circle += 1 x_in.append(x) y_in.append(y) else: x_out.append(x) y_out.append(y) # ---------------------- 计算π估算值 ---------------------- pi_estimate = 4 * in_circle / total_points print(f"总投点数:{total_points}") print(f"圆内点数量:{in_circle}") print(f"估算得到 π = {pi_estimate:.6f}") # ---------------------- 手搓绘制图形 ---------------------- plt.figure(figsize=(6, 6)) # 绘制圆内、圆外散点 plt.scatter(x_in, y_in, color="#2E86AB", s=1, label="圆内点") plt.scatter(x_out, y_out, color="#A23B72", s=1, label="圆外点") # 画出单位圆轮廓 circle = Circle((0, 0), 1, color="black", fill=False, linewidth=2) plt.gca().add_patch(circle) # 画布设置 plt.xlim(-1.1, 1.1) plt.ylim(-1.1, 1.1) plt.title("蒙特卡罗方法随机投点图形", fontsize=13) plt.xlabel("X") plt.ylabel("Y") plt.axis("equal") plt.legend() plt.grid(alpha=0.3) plt.show()五、代码运行结果说明
- 控制台输出:打印总点数、圆内点数、估算 π 值;投点数量越大,结果越接近 3.14159。
- 弹出可视化图形: 蓝色小点:落在单位圆内部;红色小点:落在正方形但圆外部;黑色轮廓是单位圆。
图形就是蒙特卡罗方法最直观的展示,大量随机点堆积,肉眼就能看出圆形轮廓。
六、拓展思考(作业加分)
- 修改
total_points参数:比如 1000、10 万,观察 π 估算精度变化,理解大数定律。样本少时误差很大,样本足够大,结果收敛。 - 拓展:可以用蒙特卡罗计算任意曲线围成的面积,不限于圆形。
- 缺点:蒙特卡罗属于随机模拟,结果每次运行都会有微小波动,属于概率方法,不是精确求解。
七、总结
蒙特卡罗本质就是用随机模拟代替复杂积分计算。本次手搓图形,没有调用现成的蒙特卡罗封装包,自己实现随机采样、点的判断、绘图可视化,既能看到图形效果,又完成数值估算。 这个小案例可以作为 Python 程序设计、数值计算课程作业。