MOPSO多目标粒子群优化算法可设置多个目标函数进行寻优pbest更新采用支配方式更新即下一个个体的所有目标优于上一个个体时进行更新否则以一定概率更新;gbest采用非劣解方式进行更新即所有个体的目标与第一个个体目标比较最终确定非劣解集合粒子群优化PSO玩过多目标版本的都知道这玩意儿在解多目标问题的时候比传统算法更带劲儿。今天咱们就聊点MOPSO的骚操作——怎么让一群粒子在多个目标函数里找到最优解还不打架。MOPSO多目标粒子群优化算法可设置多个目标函数进行寻优pbest更新采用支配方式更新即下一个个体的所有目标优于上一个个体时进行更新否则以一定概率更新;gbest采用非劣解方式进行更新即所有个体的目标与第一个个体目标比较最终确定非劣解集合先看pbest怎么玩。每个粒子都有自己的历史最优位置但这里有个坑不能只看单一目标函数。比如现在有两个目标一个要成本最低一个要性能最高。这时候新位置必须全面碾压旧位置才算更新。代码里判断支配关系的函数大概长这样def dominates(new_obj, old_obj): better_in_all True for i in range(len(new_obj)): if new_obj[i] old_obj[i]: # 假设都是最小化目标 better_in_all False break return better_in_all但现实哪有那么多完美情况当新解既不比旧的好也不比旧的差的时候咱们抛个硬币决定更不更新。这个随机性可以防止算法早熟if dominates(new_obj, current_pbest): update_pbest() elif random.random() 0.5: # 50%概率强制更新 current_pbest new_position重点来了全局最优gbest怎么选传统PSO直接选群体里最靓的仔但多目标里根本没有绝对最优。这时候得建个非劣解档案馆。每代更新时先把第一个粒子当标杆其他粒子挨个和它比archive [particles[0].position] for p in particles[1:]: is_dominated False for a in archive: if dominates(a.objectives, p.objectives): is_dominated True break if not is_dominated: archive.append(p.position) # 还要清理被新解支配的旧存档 archive [a for a in archive if not dominates(p.objectives, a.objectives)]注意这里要动态维护存档新解进来要踢掉被它支配的旧解。最后从存档里随机挑几个当gbest这样能保证搜索方向的多样性。速度更新还是经典公式但位置越界时建议用反射边界处理别直接卡死v w*v c1*rand()*(pbest_pos - x) c2*rand()*(gbest_pos - x) x x v # 边界反射 for i in range(len(x)): if x[i] lb[i]: x[i] lb[i] (lb[i] - x[i]) v[i] * -0.5 elif x[i] ub[i]: x[i] ub[i] - (x[i] - ub[i]) v[i] * -0.5最后给个实战建议目标函数数量超过3个时存档管理会指数级爆炸。这时候需要上自适应网格或者聚类算法来压缩存档规模否则内存分分钟教你做人。参数设置也别死磕文献推荐值不同问题的最优惯性权重可能差十倍动手调参才是王道。