蒙特卡洛方法听起来很神秘,但它的核心思想你其实每天都在用:通过大量重复试验,用频率来估算概率。比如掷硬币,掷一万次会发现正面朝上接近一半。蒙特卡洛方法就是把这种“笨办法”扩展到了更复杂的计算问题上。
但你有没有想过,为什么重复试验得到的平均值,会稳定在真实值附近?这背后就是大数定律在撑腰。下面我们分三步,把这个数学原理拆开看。
1. 理解大数定律在说什么
大数定律是一个数学定理,它回答了一个问题:随着试验次数的增加,样本平均值会怎样变化?
- 设 每次试验的结果是一个随机变量,比如掷骰子的点数,期望值(通俗说就是长期平均数)是 3.5。
- 做
n次独立试验,把结果加起来除以n,得到样本平均值。 - 看 当
n越来越大时,样本平均值会越来越接近期望值。
数学上,这个收敛关系可以写成:
$$\frac{X_1 + X_2 + \cdots + X_n}{n} \rightarrow \mu \quad (n \rightarrow \infty)$$
其中 $X_i$ 是第 i 次试验的结果,$\mu$ 是真正的期望值。箭头表示“收敛到”。
核心结论:样本平均数最终会“粘”在真实平均值上,试验次数越多,偏离越远越不可能。这不是巧合,而是概率上的必然。
2. 把大数定律用到蒙特卡洛上
蒙特卡洛方法的核心操作是:把你要计算的值,改写成某个随机变量的期望值,然后靠抽样平均来逼近它。
步骤是这样的:
-
构造一个随机模型,让它的期望值恰好等于你想算的结果。比如想算圆周率 $\pi$,可以在正方形里随机撒点,那么点落在内切圆内的概率是 $\frac{\pi}{4}$。这时,内切圆内点的比例就是一个随机变量,它的期望值就是 $\frac{\pi}{4}$。
-
执行大量随机抽样,记录每次的结果。比如每次撒点,判断是否落在圆内,记录一个
0或1。 -
计算所有抽样结果的平均值。当抽样次数足够多时,这个平均值就会逼近真实概率,从而反推出 $\pi$ 的近似值。
为什么能这样? 因为每次抽样得到的分析结果,就是定理中的 $X_i$。当抽样次数增加,平均值收敛到期望值,也就是你要计算的真实值。所以蒙特卡洛的“收敛”不是一种猜测,而是大数定律直接给出的保证。
3. 正确设置收敛的速度和精度
大数定律只说“会收敛”,可没说“收敛得多快”。实际使用中,你不能真的无限次抽样,所以需要量化误差。
蒙特卡洛的误差估计,来自中心极限定理(大数定律的“升级版”)。它告诉你:
- 当抽样次数为
n时,误差的波动范围大约和 $\frac{1}{\sqrt{n}}$ 成正比。 - 想把误差缩小 10 倍,需要把
n增大 100 倍。
所以,实际操作时按以下步骤做:
- 设定目标误差范围,比如允许 $\pm 0.01$。
- 估算所需抽样次数。粗略公式为:
$$n \approx \left(\frac{\sigma \cdot 2}{\text{误差}}\right)^2$$
其中 $\sigma$ 是抽样结果的标准差,可以用一小批样本先估算。
- 执行抽样,每增加一批样本,就更新一次平均值和当前误差。
- 停止当误差低于目标时,输出当前平均值作为最终结果。
注意,重复计算时要保存每次抽样的独立结果,不要用同一批数据反复计算平均值,否则会破坏独立性,大数定律就不适用了。
4. 应对两个常见使用误区
误区一:随机数不够随机。蒙特卡洛依赖独立同分布的抽样。如果程序里的随机数生成器有规律,抽样就不独立,收敛会出错。解决方法:使用质量经过验证的随机数生成库,如 Python 的 numpy.random,或者用物理随机源。
误区二:样本量太小。大数定律是“极限定理”,只保证当 n 足够大时才有好的效果。只抽几十次就做判断,误差会非常大。解决方法:至少先跑几千次,再根据误差衰减情况判断是否增加。
5. 用一个小例子完整走一遍流程
假设你想用蒙特卡洛估算一枚不均匀硬币正面朝上的概率,但不知道真实概率。做法如下:
-
编写模拟代码,每次模拟抛硬币一次,正面输出
1,反面输出0。import random def toss(): return 1 if random.random() < 0.6 else 0 # 真实概率假设为0.6 -
累计结果,计算平均值。每多抛一次,更新平均值。
n = 1000 total = sum(toss() for _ in range(n)) estimate = total / n print(estimate) -
增加
n到10000,再次运行,观察估算值是否更接近0.6。
你会发现,n 越大,估算值的波动越小,最终稳定在 0.6 附近。这正是大数定律在起作用。
蒙特卡洛方法之所以可靠,不是因为“运气好”,而是因为大数定律从数学上保证了平均值会收敛到你想要的值。你只需要确保抽样独立、次数够多,剩下的交给概率。

暂无评论,快来抢沙发吧!