蒙特卡洛模拟入门笔记:从原理到代码实践
一、什么是蒙特卡洛模拟?
蒙特卡洛模拟是一种通过大量随机实验来解决复杂问题的方法。简单说,就是用电脑模拟成千上万次随机事件,然后统计结果,以此估算一个问题的答案。
举个生活中的例子:想知道 "掷 100 次骰子,总和在 300 到 400 之间的概率",不需要真的掷 100 次骰子,而是用电脑模拟这个过程 10000 次,最后统计总和在 300-400 之间的次数占比 —— 这就是蒙特卡洛模拟的核心思路。
二、蒙特卡洛模拟的基本步骤
- 确定问题的范围(比如骰子的点数范围是 1-6)
- 生成大量随机样本(比如模拟掷 10000 次骰子)
- 计算每个样本的结果(比如每次掷骰子的总和)
- 统计分析结果(比如计算平均值、概率等)
三、用 Python 实现蒙特卡洛模拟
下面我们用一个简单的例子来实践蒙特卡洛模拟,目标是估算函数y = sin(x) + 0.5x
在x=0
到x=10
范围内的平均输出值。
步骤 1:导入需要的工具库
首先需要导入两个常用的 Python 库:numpy
用于数值计算和生成随机数,matplotlib
用于画图展示结果。
# 导入工具库
import numpy as np # 用于生成随机数和数学计算
import matplotlib.pyplot as plt # 用于绘制结果图表
步骤 2:定义要模拟的函数
我们需要一个 "目标函数",这里选择简单的y = sin(x) + 0.5x
(sin 是正弦函数,不用深究数学原理,只需要知道输入 x 会输出对应的 y 即可)。
# 定义目标函数:输入x,输出对应的y值
def target_function(x):return np.sin(x) + 0.5 * x # 函数公式:y = sin(x) + 0.5x
步骤 3:编写蒙特卡洛模拟函数
这个函数的作用是:在指定范围内随机生成大量 x 值,计算对应的 y 值,然后把所有结果存起来。
def monte_carlo_simulation(func, min_x, max_x, num_samples):"""func:要模拟的函数min_x:x的最小值(范围起点)max_x:x的最大值(范围终点)num_samples:模拟次数(样本数量)"""results = [] # 用列表存储所有模拟结果# 重复num_samples次模拟for i in range(num_samples):# 生成一个在[min_x, max_x]之间的随机x值x = np.random.uniform(min_x, max_x)# 计算这个x对应的函数值yy = func(x)# 把结果存入列表results.append(y)# 打印进度(每完成10%显示一次)if (i + 1) % (num_samples // 10) == 0:print(f"已完成 {i + 1}/{num_samples} 次模拟")return results # 返回所有模拟结果
步骤 4:设置参数并运行模拟
我们设定 x 的范围是 0 到 10,模拟 1000 次(可以自己修改次数看看效果)。
# 设置模拟参数
x_min = 0 # x的最小值
x_max = 10 # x的最大值
sample_count = 1000 # 模拟次数(样本数量)# 运行蒙特卡洛模拟
print("开始模拟...")
simulation_results = monte_carlo_simulation(func=target_function,min_x=x_min,max_x=x_max,num_samples=sample_count
)
print("模拟完成!")
运行后会看到进度提示:
开始模拟...
已完成 100/1000 次模拟
已完成 200/1000 次模拟
...
已完成 1000/1000 次模拟
模拟完成!
步骤 5:分析模拟结果
模拟得到大量 y 值后,我们可以计算它们的平均值(估算函数的平均输出)和方差(估算结果的波动程度)。
# 计算统计指标
mean_value = np.mean(simulation_results) # 平均值(期望值)
variance_value = np.var(simulation_results) # 方差(波动程度)# 打印结果
print(f"\n统计结果:")
print(f"函数的平均输出值:{mean_value:.2f}") # .2f表示保留两位小数
print(f"结果的方差(波动):{variance_value:.2f}")
运行后会得到类似这样的结果:
统计结果:
函数的平均输出值:2.63
结果的方差(波动):2.32
步骤 6:可视化模拟结果
用直方图可以更直观地看到所有 y 值的分布情况(哪些 y 值出现得更多)。
# 绘制直方图
plt.figure(figsize=(10, 6)) # 设置图表大小
plt.hist(simulation_results, # 要展示的数据bins=30, # 柱子的数量(越多越精细)edgecolor='black', # 柱子边缘颜色alpha=0.7 # 透明度(0-1)
)# 设置图表标题和坐标轴标签
plt.title('蒙特卡洛模拟结果分布', fontsize=15)
plt.xlabel('函数输出值(y)', fontsize=12)
plt.ylabel('出现次数', fontsize=12)
plt.grid(alpha=0.3) # 显示网格线(alpha控制透明度)# 显示图表
plt.show()
运行后会看到一个直方图,横轴是函数的输出值 y,纵轴是这个 y 值出现的次数。从图中可以清晰地看到:大部分结果集中在 2-3 之间,和我们计算的平均值(2.63)一致。
四、尝试修改参数,观察变化
为了更好地理解蒙特卡洛模拟,可以尝试修改以下参数,看看结果会发生什么变化:
- 改变
sample_count
(比如改成 100 或 10000):模拟次数越多,结果通常越稳定。 - 调整
x_min
和x_max
(比如改成 0 到 20):x 的范围变了,函数的输出范围也会变化。 - 修改
target_function
(比如改成return x**2
计算平方函数):不同的函数会有不同的结果分布。
五、总结
蒙特卡洛模拟的核心就是:用大量随机实验代替复杂计算。它不需要我们推导复杂的数学公式,只需要设定好范围,让电脑重复足够多次实验,就能估算出问题的答案。这种方法在金融、天气预测、游戏设计等很多领域都有广泛应用,掌握它能帮你解决很多看似复杂的问题!