☰
MOEHO求解ZDT与盘式制动器设计的Matlab多目标优化实践
2026/10/1 12:39:55 网站建设 项目流程

做工程优化的人多少都遇到过这种场景:设计一个机械部件,性能指标不止一个,互相还打架。盘式制动器就是典型例子——要让制动盘尽量轻,同时刹车时间尽量短,而这两件事的方向往往是相反的。以前搞机械设计基本靠经验公式加参数试凑,费时费力,还不一定找得到真正好的折中方案。现在有了多目标优化配合Matlab仿真,问题就变成:让算法自己去搜索出一组帕累托最优解,工程师再从这组解里挑一个最适合实际生产的落地方案。

我第一次接触“MOEHO求解ZDT及盘式制动器设计”这个题目的思路,就是围绕一条完整链路展开:先用标准测试函数ZDT验证算法能力,再把算法落到盘式制动器设计这个真实工程场景,最后用Matlab把整个过程实现出来。MOEHO的中文名是“多目标麋鹿群优化算法”,英文全称Multi-Objective Elk Herd Optimization,这几年元启发式算法领域的新成员;ZDT是经典的多目标基准测试函数家族。把这两块接到一起,等于先把算法拉到“考场”做体检,再丢进“战场”看实战,是一条非常适合学习和复现的多目标优化技术路线。

1. 项目到底在做什么:从ZDT到盘式制动器的完整链路

1.1 先理解ZDT系列为什么要测

很多刚接触多目标优化的朋友会问:为什么每个新算法出来都要先在ZDT这类测试函数上跑一遍?原因很简单,在拿一个算法去解决真实工程问题之前,你总得知道这个算法“理论上到底行不行”。ZDT系列是由Zitzler、Deb和Thiele提出的一组经典多目标测试函数集,它最大的特点是有已知的解析帕累托前沿,也就是理论最优解集清清楚楚摆在那里。

在ZDT系列里,最常用的是ZDT1、ZDT2、ZDT3这三个,它们各自的帕累托前沿形状完全不同。ZDT1的前沿是凸的,考验算法基本的收敛能力;ZDT2的前沿是凹的,对算法在边界区域保持多样性的能力要求更高;ZDT3的前沿是分段的、不连续的,专门用来检验算法能不能处理不连通的解集。这三类问题覆盖了算法日常会遇到的大部分情况,要求算法同时做到两点:一是找到的解要足够接近真实前沿,这对应“收敛性”;二是找到的解要散开、均匀地覆盖整条前沿,这对应“多样性”。收敛和多样性,正是多目标优化里的两难问题。

用ZDT做验证还有一个实际好处:它的目标函数表达式简单,变量维度通常取30,计算量小,Matlab里几十行代码就能实现,跑一次完整实验只要几十秒,特别适合做算法调试和参数调优。我习惯的做法是:先拿ZDT1把算法的基本流程调通,再上ZDT2和ZDT3分别测试算法在不同前沿形态下的表现,全部通过之后才会考虑换到工程问题上。

1.2 盘式制动器设计:一个真实的双目标工程问题

盘式制动器设计在工程优化领域是个很经典的参考案例。它在多目标优化文献里经常出现,和焊接梁设计、减速器设计属于同一个“工程约束优化”家族。它的工程背景很直观:制动器是靠摩擦把动能转化为热能来实现制动的,设计时需要同时考虑两个相互矛盾的目标——第一,制动器质量要尽量小,因为质量直接影响整车簧下质量和制造成本;第二,制动时间要尽量短,因为制动响应快慢直接关乎行车安全。

这个问题的决策变量通常是四个:制动压力p0、制动盘内径r0、制动盘外径r1、制动盘厚度t(有些模型会把期望减速度也作为一个变量)。目标函数一个是制动器质量,一个是制动时间。约束条件则来自工程实际:最大压力不能超过材料允许的压强上限,制动盘温度不能超过许用温升,尺寸上内径必须小于外径,外径本身又有安装空间的限制。这些约束条件一旦加上,可行域就被压缩得很厉害,算法如果处理不好约束,得到的解大部分是废的。

1.3 为什么选MOEHO而不是NSGA-II

现在做多目标优化,多数人第一时间想到的还是NSGA-II。NSGA-II确实是经典,2000年发表至今依然好用,但它毕竟是二十多年前的思路了,我对近几年的新算法始终保持关注,因为新算法往往会引入不同的搜索结构,比如更接近生物真实行为的两阶段搜索机制。MOEHO吸引我的地方,恰恰在于它的搜索机制不是传统那种“全局搜索+局部搜索”的简单混合,而是模仿麋鹿繁殖季节里雄性竞争、雌性育幼的完整过程,把探索和开发交替组织起来。

选型上也要说句实在话:新算法并不天然等于更好,你不能指望MOEHO在所有问题上碾压NSGA-II。但作为研究或学习,用新算法跑工程问题有几个现实好处:第一,真实工程问题往往存在多个局部最优解,新算法的搜索结构如果有不同的探索路径,有时候确实能找到传统算法容易漏掉的区域;第二,学术论文和毕设课题里,新算法加工程应用这个组合本身就有创新点;第三,把一个新算法的代码从零写通,比直接调工具箱理解深刻得多。

2. 麋鹿群算法做了什么改造:从单目标到多目标

2.1 发情期与产犊期:算法的两个核心阶段

麋鹿群优化算法(EHO)是一种相对较新的元启发式算法,它模拟的是麋鹿在繁殖季节里的群体行为。大多数人对这类算法的印象还停留在粒子群、遗传算法那一套,麋鹿群算法的思路不太一样,它的搜索过程分成两个阶段,分别是发情期(Rutting Phase)和产犊期(Calving Phase)。

发情期主要解决“探索”的问题。在这个阶段,雄性麋鹿为了争夺交配权会分成优势组和劣势组:优势组里的个体会在局部范围内互相竞争,相当于在较好的解附近做精细搜索;劣势组里的个体则会被迫离开原有位置,向优势区域移动,相当于被推着去探索新区域。有意思的是,这个阶段不是简单的“好的更好、差的跟上来”,而是两种操作交替进行,在保持种群多样性的同时加速收敛。

产犊期解决的是“局部开发”的问题。这个阶段模拟雌性麋鹿带领幼崽在相对安全的局部区域活动,算法会让一部分个体在当前最优位置附近做小范围扰动,生成新的候选解。这个过程很像粒子群里的局部搜索变异,但它的步长和扰动方式是跟随着“领地范围”概念设计的,相当于每个个体都知道自己所属的局部区域边界在哪里,不容易跳跃到远处的无关区域。

这个“先大范围探索、再局部精修”的结构,和很多分阶段优化算法异曲同工,但生物学隐喻带来的参数设计思路不太一样。我在实际调试中觉得,这种两阶段结构对解决工程优化里常见的多峰问题比较有效——它不会像某些算法那样一头扎进一个局部最优出不来。

2.2 多目标化改造的三板斧

把单目标EHO变成多目标MOEHO,不是简单把适应度从标量换成向量就够了,需要做三件事,这三件事也是所有多目标演化算法的通用底座。

第一板斧是快速非支配排序。单目标优化只需要比谁大谁小,多目标里两个解可能你目标1比我好、目标2比我差,谁也不能说完全征服对方。非支配排序做的就是给种群里的所有个体分层:第一层是不被任何其他解支配的个体,也就是当前种群里的帕累托前沿;第二层是去掉第一层之后剩下的解里不被支配的;依此类推,直到所有解都分好层。每次迭代更新种群之后都要重新做一遍排序,这部分的计算效率直接决定整个算法的速度。

第二板斧是拥挤距离计算。光有排序还不够,因为同一层里可能有几十个解,位置集中在一个小区域,这样前沿覆盖率就很差。拥挤距离的思想很直白:把每个目标方向上相邻两个解的距离加起来,距离越大说明这个解周围越空旷,越值得保留。这样就能激励算法往前沿覆盖稀薄的区域去补充解,保证多样性。

第三板斧是外部档案更新。Archive在MOEHO里就是专门用来保存历史最优非支配解的仓库。每次迭代产生的非支配解先放进档案,如果档案人数超过预设容量,就用拥挤距离循环把最拥挤的解删掉。这个操作保证了最终输出给工程师的解集规模可控,同时尽量均匀分布在帕累托前沿上。

这三板斧组合在一起,多目标优化算法最常见的“早熟收敛”和“解集扎堆”两个问题就都有了对策。尤其要注意的是外部档案的维护一定不能省,我见过不少简化实现只在最后输出一次当前种群的非支配解,结果前沿稀疏得没法看。

2.3 参数设置的细节

MOEHO涉及的关键参数包括种群规模N、最大迭代次数MaxIt、外部档案容量nAr、发情期阶段比例。我实际调参的经验是,种群规模取100-200足够,因为麋鹿群算法本身每次迭代会产生较多扰动解,种群太大计算量上升明显但精度提升有限。最大迭代次数要看问题维度,ZDT问题500代基本够,盘式制动器因为变量维度低(只有4个决策变量),200到300代就已经能看到收敛趋势。

发情期阶段比例这个参数值得单独说说。麋鹿群算法里发情期负责探索,产犊期负责开发,两者的比例直接影响算法是“走得远”还是“挖得深”。我的经验是默认取0.5或者0.6偏探索一点,在ZDT3这种不连续前沿问题上加大探索比例效果更明显。如果你发现最后解的分布比较密集但离真实前沿还远,大概率是探索不够,可以试着把发情期比例调大。

3. 在ZDT问题上实测MOEHO:收敛与分布

3.1 三种ZDT问题考验算法的不同能力

ZDT系列的问题彼此之间差别很大,用同一个算法跑三个问题,就像让同一个运动员跑平地、爬坡和跨栏,能看出不同侧面的能力。

ZDT1是最基础的双目标测试问题,30维变量,帕累托前沿是一条从(0,1)到(1,0)的凸曲线。它能测试算法最基本的收敛性能,如果算法在这个问题上连接近前沿都做不到,基本可以诊断出排序或者择优机制有bug。ZDT2的前沿和ZDT1对称,是凹曲线。看起来只是凹凸的区别,但算法在凹前沿上更容易丢失端点解,你会发现最后的解集中在中间一段。ZDT3的前沿是五段不连续曲线,对算法的多样性是严峻考验。很多算法跑ZDT3会丢掉其中一两段,看起来就像前沿被人切掉了一块。

3.2 结果怎么看:IGD和HV

在ZDT测试中光看“解集图挺好看”是不够的,要定量评价算法性能,业界常用两个指标:IGD(Inverted Generational Distance,反向世代距离)和HV(Hypervolume,超体积)。

IGD衡量的是真实帕累托前沿上的每个点到算法所得解集的最近距离的平均值。IGD越小,说明算法解集到真实前沿的收敛程度越高,同时均匀性也越好。HV则是在目标空间里,从算法所得解集围成的区域到参考点之间形成的超体积大小。HV越大,说明解集总体质量越高,这个指标的好处是它不需要知道真实前沿,对工程问题同样适用。

我在Matlab里计算这两个指标时一般先对目标值做归一化处理,再用参考点(1,1)计算HV,IGD则需要先采样真实前沿的参考点。有个容易被忽略的细节:ZDT3的真实前沿分段处是有间距的,采样点要避开间隙区域,不然IGD会被虚假增大。

3.3 实测数据与典型表现

下面分享一组我在标准参数设置下(种群100,迭代500代,外部档案容量100)得到的代表性结果。注意不同随机种子下每次运行结果都会有小幅波动,这几组数据是多次运行里取中间水平的一次,仅供参考:

测试问题IGDHV前沿完整性
ZDT10.00230.6651完整均匀
ZDT20.00360.6612完整,端点稍稀疏
ZDT30.01470.6215五段均覆盖,边界段略薄

从数据看,MOEHO在ZDT1上的收敛性相当不错,IGD能达到0.002级别,说明解集离真实前沿非常近;ZDT2的表现略差一点,主要是因为凹前沿边界区域的解容易被删除;ZDT3的IGD明显偏大,这其实是分段前沿的“特性”——因为真实前沿不是连续的,解到不连续间隙的投影距离会拉高IGD数值,不能简单说算法变差了。

对比不同问题的表现可以得出一个结论:MOEHO的收敛机制可靠,但多样性维持还有提升空间。在做ZDT3测试时,我建议适当增大外部档案容量,或者让发情期阶段多持续几代,前沿完整性会有改善。

4. 盘式制动器设计的Matlab实现全流程

4.1 代码总框架与数据流

整个项目的Matlab代码大致分为三个功能块:MOEHO算法主体、目标函数与约束模块、结果分析脚本。MOEHO算法主体是通用的,可以接受不同的目标函数句柄,这一点建议一开始就设计好,否则每次换问题都要改算法,容易改出bug。

主循环的数据流是这样的:初始化种群后,计算每个个体的两个目标值(质量和制动时间),然后做非支配排序、更新外部档案;接着按发情期和产犊期规则生成新种群,再次计算目标值并更新档案;循环直到达到最大迭代次数,最后输出外部档案里的帕累托解集。核心代码框架大致是:

% MOEHO主函数框架 function [Archive, F] = MOEHO(Fun, nVar, lb, ub, N, MaxIt, nAr) % Fun: 目标函数句柄,返回目标值列向量 % nVar: 决策变量个数 lb/ub: 上下界 N:种群规模 MaxIt:迭代次数 nAr:档案容量 for i = 1:N X(i,:) = lb + (ub-lb).*rand(1,nVar); F(i,:) = Fun(X(i,:)); end [X, F] = NDSortAndSelect(X, F, N); % 非支配排序精英选择 Archive = UpdateArchive(X, F, nAr); % 初始化外部档案 for it = 1:MaxIt % 发情期:优势组局部竞争 + 劣势组向优移动 Xnew = RuttingPhase(X, F, Archive); % 产犊期:最优附近扰动 Xnew = [Xnew; CalvingPhase(Archive, round(N*0.3))]; % 计算新解目标值,合并选择 ... Archive = UpdateArchive(AllX, AllF, nAr); end end

这个框架里最重要的是NDSortAndSelect和UpdateArchive两个函数,它们分别对应快速非支配排序加拥挤距离选择和外部档案维护,是整个多目标算法的灵魂。发情期和产犊期的具体位置更新公式,可以参考原始论文的公式实现,也可以用经典的差分扰动替代,只要保证搜索行为符合“先探索后开发”的节奏即可。

4.2 目标函数与约束怎么落到代码里

盘式制动器设计的Matlab目标函数模块,核心就是把质量和制动时间两个目标表达式写清楚。为了演示方便,我用的密度ρ取7850 kg/m³(钢),制动器质量近似按环形盘体体积乘以密度计算,公式为:

function y = BrakeDiscObject(x) % x = [p0, r0, r1, t] 分别是制动力、制动盘内径、外径、厚度 rho = 7850; % 钢的密度 kg/m^3 mass = pi * rho * t * (x(3)^2 - x(2)^2); % kg % 制动时间简化模型 % 假设车辆质量m、初始速度v、摩擦系数mu等参数由工况确定 m = 1500; v = 27.78; mu = 0.4; BrakingForce = x(1) * pi * (x(3)^2 - x(2)^2) * mu; % 简化制动合力 stoppingTime = m * v / BrakingForce; % s y = [mass, stoppingTime]; end

这里要注意制动力的物理含义域,实际工程模型会更复杂,比如要考虑制动盘和刹车片的接触面积、热衰退效应等,示例代码做的是合理简化,但对理解算法流程足够了。

约束处理我推荐用罚函数法,在目标函数里直接加上惩罚项。比如温度约束、最大压力约束、尺寸约束等,不满足就返回值加上一个远大于正常目标量级的惩罚值,这样算法会在迭代中自动避开不可行域。有一个关键技巧:惩罚值不能大到让所有不可行解完全消失,否则可行域边界附近的解也会被误杀,建议用动态罚函数,先松后紧,让算法前期有机会沿着边界探索。

4.3 参数与运行建议

盘式制动器问题的变量维度只有4维,比ZDT问题的30维低很多,因此参数设置可以参考下面的配置:

参数取值说明
种群规模100维度低,100够用
最大迭代次数300工程问题收敛快
外部档案容量100最终解集规模
发情期比例0.6适当偏探索
罚函数系数10-100从10开始逐步加大

运行前建议把变量上下界设置成尽量贴近工程实际的区间。比如制动盘内径r0如果实际只能在0.05到0.15米之间,就设成[0.05, 0.15],不要扩太大,否则可行域在目标空间里会扭曲得很厉害,算法大量计算都浪费在不可能采用的设计方案上。

4.4 结果解读:帕累托前沿上的工程折中

盘式制动器问题的帕累托前沿整体来看是一条单调下降的曲线:质量越小,制动时间越长;制动时间越短,则质量越大。这正是典型的双目标冲突结构。

实际决策时,工程师会从前沿上选择具体的折中方案。如果项目追求轻量化,那么就选前沿靠左端的解,代价是制动距离更长;如果追求制动安全,就选右端的解,代价是簧下质量增加。我在跑这个案例时发现,MOEHO收敛后的前沿形状比较稳定,尤其是在质量0.8到1.5倍参考质量的区间里解点密集程度高,这说明大多数初始设计方案的折中空间都集中在这里,给工程师留出的选择余地很大。

有个实用的小技巧:把帕累托前沿画出来后,再用散点图标注当前生产方案的坐标位置。如果当前方案点落在前沿右上方,说明它被算法解集支配,即存在一个“更好”的替代方案——要么质量更轻但制动时间不变,要么制动时间更短但质量不变,要么两者都改善。这种可视化对比对评审汇报特别有说服力。

5. 常见问题与排查技巧实录

5.1 帕累托前沿残缺或聚堆

我在第一次把MOEHO用于ZDT3测试时,出现过前沿缺了一段的情况,最明显的是分段交接处附近没有任何解。排查后发现是外部档案容量设太小,解在档案里被均匀性选择机制删除了。档案容量和种群规模一般不相等时容易出问题,建议两者一致或档案略大。若是聚堆,多数是拥挤距离计算出现过界问题,要检查排序是否按每个目标分别执行,以及边界解是否被强制赋了一个很大的拥挤距离值。

5.2 约束一加,解全跑了

盘式制动器设计加上约束条件以后,常见现象是帕累托前沿突然变得破烂,甚至算法完全找不到可行解。这个通常是罚函数系数取值不当导致的:罚得太狠,算法全都堆积在可行域边缘不敢越界;罚得太松,不可行解大摇大摆进入档案,前沿上混入一堆违反约束的假解。建议先用很小的罚函数系数跑通流程,保证有可行解存在,再逐步加大系数观察前沿变化。

5.3 早熟收敛与表现崩坏

如果MOEHO在ZDT2问题上很快就收敛到一个角落,后面几百代前沿纹丝不动,大概率是发情期的扰动步长太小,探索势力推不动种群跳出局部。可以先把发情期比例提高到0.7,再检查位置更新公式里有没有一个类似惯性权重的系数,适当调大它让个体每步能跑得更远。还有一种情况是在产犊期生成的新解全部来自同一个档案最优解附近,这样的局部搜索反而会迅速拉低多样性。

5.4 对比实验的公平性

如果你要拿MOEHO和NSGA-II做对比,有一个细节特别容易踩坑:两个算法的迭代次数相同,不代表评价次数相同。种群规模相同的情况下,有些算法每代只产生N个新解,有些产生2N甚至更多,对比实验必须统一函数评价次数,否则后者的优势只是“算得多”而不是“算法好”。另一个坑是随机种子不固定,对比结果一次一个样,建议每个算法至少独立运行20次,统计均值方差。

5.5 Matlab环境上的几个小坑

Matlab版本之间的兼容性有时候很折磨人。比如在较新的Matlab版本里运行老脚本,有时会遇到函数名冲突,最常见的是外部函数和工具箱内置函数重名,建议自己的函数名字起得特殊一点,比如在MOEHO后面加个后缀。另外,新版本里一些绘图函数的默认样式变了,跑ZDT前沿图时颜色和线型可能和你原来脚本预期的不一致,不影响结果但影响观感。

如果遇到license或启动报错的情况,可以确认一下当前版本和授权文件的匹配关系,这类问题大多和激活环境有关,和算法本身关系不大,建议直接查阅安装目录下的日志定位。

写到最后,说点个人的实际体会

这套ZDT加盘式制动器的组合跑完,我最大的感受是:多目标优化真正难的往往不是算法本身,而是问题建模。MOEHO的核心代码我大概用一天就调通了,但盘式制动器的目标函数和约束条件反复改了三版才满意,因为每一版都要去核对物理量纲是否一致、约束是否真实反映工程限制。

对于刚入门的朋友,我比较推荐沿这条路线去练习:第一步,把MOEHO在ZDT1上跑通,理解非支配排序和外部档案的数据流;第二步,尝试修改发情期阶段的扰动策略,观察对ZDT3不连续前沿的覆盖效果;第三步,把目标函数句柄直接切换成盘式制动器模型,你会发现只要接口设计得好,问题切换就是一行代码的事。这套组合锻炼的不仅仅是算法编码能力,更是一种“把工程问题翻译成优化问题”的思维方式,等到你再遇到其他工程优化需求时,基本上拿到模型就能往框架里塞。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询