本文最后更新于223 天前,如有错误请发送邮件到yaoshengliy@gmail.com
前言
时间:3月30日
题目与要求:在本次 Python 课程的课后作业中,需要使用 蒙特卡罗方法“手搓”出一个图形。本质上,这是随机模拟与可视化图形的结合,通过模拟次数的大小来观察图形的变化,总结出差异与结论。
蒙特卡罗方法是一种基于随机采样的数值计算方法,其核心思想是在无法直接求解问题时,通过大量的随机实验进行估算。
方法与分析
目标图形
在本次练习中,我选择手搓的目标图形是:爱心-Heart
实现思路
- 确定绘图区域:选择一个二维平面区域,
[x_min, x_max] × [y_min, y_max] - 设定判定函数:写出目标图形对应的数学表达式或逻辑函数,用于判断一个随机点是否“落在图形内部”
- 进行随机投点:
- 生成大量均匀分布的随机点;
- 对每个点进行判定;
- 记录命中图形的点。
- 可视化结果:使用 Matplotlib 绘制命中点和未命中点,直观展现图形边界
代码实现
以下是代码实现:
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置随机种子,保证结果可重复
np.random.seed(42)
# 采样点数量
N = 50000
# 随机生成点
x = np.random.uniform(-1.5, 1.5, N)
y = np.random.uniform(-1.5, 1.5, N)
# 判定是否在爱心区域内
def in_heart(x, y):
return (x**2 + y**2 - 1)**3 - x**2 * y**3 <= 0
# 向量化判断
mask = in_heart(x, y)
# 可视化结果
plt.figure(figsize=(8, 8), dpi=120)
plt.scatter(x[mask], y[mask], color='#FF69B4', s=1, label='内心')
plt.scatter(x[~mask], y[~mask], color='#D3D3D3', s=1, label='外部')
plt.title(f'采样点数量{N}', fontsize=16, color='#C71585')
plt.axis('equal')
plt.axis('off')
plt.legend(loc='upper right', fontsize=10)
plt.tight_layout()
plt.show()
通过指定不同的采样点数量,可以明显感知图片的轮廓清晰程度、随机性、随机误差等等。我分别使用采样点数量为10000、50000、100000、1000000个进行绘制,结果如下。




由上述的图片说明,不同采样点数量所产生图片的噪点不同。
- N = 10,000:
- 爱心形状粗略可见,但边缘模糊,灰色背景点较为显眼,图像呈现较高的随机性。
- N = 50,000:
- 图形轮廓明显改善,爱心形态较为完整,但仍存在小部分噪点。
- N = 100,000:
- 爱心图案更加清晰饱满,边界趋于平滑,图形识别度高,已接近理想图形。
- N = 1,000,000:
- 采样点极其密集,图像效果近乎“连续曲面”,几乎无噪点干扰,完美呈现爱心函数本身。
结论
蒙特卡罗方法的核心在于 利用大量随机采样模拟复杂问题的数值解,随着样本点的数量增加,图形将会逐渐接近真实图形,这就是蒙特卡罗的典型特性:慢收敛、强通用、易实现。这个过程不仅帮助我们理解蒙特卡罗方法的基本原理,也揭示了它在复杂几何计算和数值模拟中的强大潜力,是一个将数学原理、计算实践与可视化直觉完美结合的经典入门案例。






