4. 蒙特卡洛模拟:随机数生成与正态分布、模拟次数与置信度、蒙特卡洛模拟流程

蒙特卡洛模拟,说白了就是“用大量随机抽样来逼近真实结果”。

我在做光学系统公差分析时,最怕的就是“拍脑袋”定公差。你想想看,一个镜头几十个镜片,每个镜片有曲率、厚度、偏心、倾斜……如果每个参数都按最坏情况叠加,那公差预算根本没法做。蒙特卡洛模拟就是用来解决这个问题的——它告诉你:在真实生产条件下,你的系统到底能有多大概率满足指标

4.1 随机数生成与正态分布

蒙特卡洛模拟的第一步,是生成符合实际生产分布的随机数。

我见过不少新手直接拿均匀分布来模拟公差,结果算出来的良率虚高。为什么?因为实际生产中,大多数工艺参数服从的是正态分布(也叫高斯分布)。

核心概念:

  • 均匀分布:每个值出现的概率相等。适合模拟“未知分布”或“最坏情况”的边界检查。
  • 正态分布:中间值概率高,两端概率低。适合模拟实际加工误差。

在光学设计软件(如Zemax、Code V)中,通常内置了正态分布随机数生成器。但如果你自己写脚本,比如用Python,可以这样生成:

import numpy as np

# 生成10000个符合正态分布的随机数
# 均值=0,标准差=1(标准正态分布)
samples = np.random.normal(loc=0, scale=1, size=10000)

# 实际应用中,你需要根据公差范围映射
# 比如:厚度公差 ±0.05mm,3σ对应这个范围
thickness_tolerance = 0.05  # 半宽
sigma = thickness_tolerance / 3  # 假设3σ覆盖99.7%
actual_thickness = nominal + np.random.normal(0, sigma, size=N)

我的经验:

我个人习惯用3σ原则来设定标准差。也就是说,如果图纸上标了±0.05mm的公差,我默认这个范围对应3σ(覆盖99.7%的样本)。这样模拟出来的结果更贴近实际产线数据。

这里有个坑:截断正态分布。实际加工中,超出公差范围的产品会被筛选掉。所以如果你直接生成正态分布,可能会得到一些“超差”的样本。我一般会加一个判断:

# 截断:超出公差范围的重新生成
while True:
    delta = np.random.normal(0, sigma)
    if abs(delta) <= thickness_tolerance:
        break

嗯,这样更符合实际。

4.2 模拟次数与置信度

蒙特卡洛模拟里有个灵魂问题:到底要跑多少次?

你跑100次和跑10000次,结果可能差很多。但跑太多又浪费时间。我记得有一次帮客户做投影镜头公差分析,他要求良率精度到±0.5%。我一开始跑了500次,结果置信区间太宽,根本没法用。后来加到5000次,才稳定下来。

这里有个经验公式:

模拟次数 N 与置信度的关系:

对于二项分布(良率/不良率),置信区间半宽 ≈ 1.96 × √(p(1-p)/N)

其中 p 是估计的良率,1.96 对应 95% 置信度。

举个例子:

  • 假设你预估良率 p = 90%
  • 想要置信区间半宽 ≤ 1%
  • 那么 N ≥ (1.96² × 0.9 × 0.1) / 0.01² ≈ 3457 次

所以,3000-5000次是光学系统公差分析中比较常见的模拟次数。如果系统特别复杂(比如几十个镜片),我可能会跑到10000次。

注意:

模拟次数不是越多越好。当N超过一定值后,精度提升非常缓慢,但计算时间线性增长。我个人建议:先跑500次看看趋势,再根据置信度需求调整到3000-5000次

4.3 蒙特卡洛模拟流程

好了,我们把整个流程串起来。我在实际项目中,通常按下面这五步走:

  1. 定义输入参数及其分布
    • 列出所有公差项:曲率、厚度、偏心、倾斜、折射率、阿贝数等
    • 为每个参数指定分布类型(正态/均匀)和标准差
  2. 生成随机样本
    • 根据分布类型生成N组随机数
    • 每组代表一个“虚拟镜头”
  3. 执行光学仿真
    • 对每组参数,计算系统性能指标(MTF、波前差、畸变等)
    • 记录每个样本是否满足指标
  4. 统计分析
    • 计算良率:满足指标的样本数 / 总样本数
    • 计算性能分布的均值、标准差、P95/P5等
  5. 灵敏度分析与优化
    • 找出对性能影响最大的公差项(“罪魁祸首”)
    • 收紧关键公差,放宽非关键公差

下面这张图是我自己总结的蒙特卡洛模拟流程,你可以对照着看:

蒙特卡洛模拟流程图 步骤1:定义输入 公差项 + 分布类型 + 标准差 步骤2:生成随机样本 N组随机数(N=3000~5000) 步骤3:光学仿真 计算MTF/波前差等指标 步骤4:统计分析 良率、均值、P95/P5 步骤5:灵敏度分析与优化 找出关键公差,调整分配 迭代优化,直到良率达标 关键点: • 分布类型要符合实际(优先正态分布) • 模拟次数3000~5000次,保证95%置信度 • 灵敏度分析是优化公差的“指南针”

流程看起来简单,但实际执行时有很多细节。我举一个真实案例:

案例:手机镜头模组公差分析

我曾经做过一个6P(6片塑料镜片)的手机镜头。初始设计时,MTF在中心视场能到0.6。但按常规公差跑蒙特卡洛,良率只有40%。

我通过灵敏度分析发现:第3片镜片的偏心公差是罪魁祸首。于是我把这个偏心公差从±0.03mm收紧到±0.015mm,同时把其他几个不敏感的公差放宽了20%。

调整后,良率从40%提升到了85%。这就是蒙特卡洛模拟的价值——用数据说话,而不是凭感觉

避坑指南:

我曾经犯过一个错误:在生成随机数时,没有设置随机种子(random seed)。结果每次跑出来的结果都不一样,导致我花了半天时间在“找规律”,其实只是随机波动。后来我养成了习惯:每次模拟前固定随机种子,这样结果可复现,方便调试。

最后说一句:蒙特卡洛模拟不是万能的。它假设所有公差项是独立的,但实际生产中,有些参数是相关的(比如曲率和厚度可能同时受温度影响)。如果你遇到这种情况,可以考虑用拉丁超立方抽样相关随机数生成来改进。不过那是进阶内容了,今天先聊到这里。


公众号:蓝海资料掘金营,微信deep3321