看到这篇论文标题的时候,我第一反应是:又是一个给粒子群换壳做局部搜索的改进工作?但真正把 LDS 初始化、CG 局部搜索和异构综合学习粒子群算法放在同一个框架里走一遍实验后,我的看法变了。这篇 SEVC 二区工作本质上不是做加法,而是把“初始采样质量”“进化轮次分工”和“后期精修策略”三个相对独立的环节,用非常克制的节奏串了起来。适合正在做群体智能算法改进的研究生,也适合想拿 PSO 做连续优化工程的算法工程师阅读。下面我会把算法的设计动机、核心实现细节、以及我自己按同样配置复现出来的性能数据,全部拆开讲。
1. 异构综合学习框架的瓶颈与新组合思路
1.1 从原始 PSO 到异构双群综合学习的演进
很多新手容易把 PSO 想成一个万能优化器,实际跑起来就会发现经典 PSO 在单峰函数上收敛很快,可一到 Rastrigin、Griewank 这类多峰函数上,经常在迭代中期就陷入局部最优。根本原因在于所有粒子共享同一个全局最优 gbest,社会项会把整个种群迅速拉向当前找到的最好位置,一旦这个位置是局部陷阱,整个种群几乎没有自救能力。
后续改进主要沿着两个方向走:一是让粒子不要只向 gbest 学习,CLPSO 提出综合学习策略,每个粒子的每一维都可以独立地从其他粒子的历史最优中学习,相当于把“跟风”变成“选择性借鉴”。二是引入异构种群,HCLPSO 把种群分成勘探子群和开发子群,勘探组主要负责大范围搜索,开发组专注于局部细化。这样设计的好处是勘探子群不需要被全局最优束缚,能给开发组持续提供多样化的候选区域。
HCLPSO 在 CEC 测试集上比 CLPSO 有明显进步,但依然存在两个容易被忽略的短板。第一,初始种群仍然靠均匀随机分布生成,高维空间里伪随机数的分布非常不稳定,不同运行之间种群覆盖率差异很大。第二,开发子群虽然负责精细搜索,但 PSO 的速度-位移更新本质上是在做一阶信息融合,粒子很难在高维空间中精确滑入极小值点。这就是论文引入低差异序列和共轭梯度法的直接动机。
1.2 用低差异序列提升“第一公里”的种群质量
绝大多数 PSO 改进都在修改速度更新公式,却很少有人质疑初始种群是怎么产生的。标准做法是从均匀分布 U(0,1) 里抽取随机数,乘以边界范围生成初始坐标。这个做法本身不坏,但在高维空间里有个很麻烦的特点:伪随机数会产生聚集和空洞,某些区域粒子扎堆,某些区域几乎没人探索。
低差异序列和普通伪随机数的本质区别在于:它生成的样本不是“看起来随机”,而是刻意追求空间分布上的均匀性。Halton 序列、Sobol 序列都属于这一类。比如在二维平面生成 100 个点,伪随机数分布有明显空隙,Sobol 序列却能让每个子区域的点数大体一致。把这种均匀性放到 30 维问题里,初始种群对搜索空间的覆盖会更完整,后续进化也就不容易因为开局偏置而漏掉一些潜在最优区域。
论文用低差异序列替代随机初始化,本质上是在改善粒子群算法的“第一公里”。这一步的收益在单次运行中往往看不明显,但如果你把相同算法跑 30 次再对比平均值和标准差,就会发现初代种群的方差显著下降,算法整体的稳定性好了很多。这个特性对 SCI 级别的实验统计非常关键,因为审稿人最讨厌看到的就是高方差、不可复现的结果。
1.3 用共轭梯度法补上“最后一公里”的收敛精度
粒子群这类基于群体的算法适合做全局勘探,却不擅长在极小值附近做精细收敛。原因很直观:速度更新依赖惯性权重和历史最优,粒子会在最优解附近来回震荡,很难像牛顿法那样精准定位。梯度下降虽然局部收敛能力强,但普通最速下降法在病态函数上会出现锯齿形路径,收敛速度极慢。
共轭梯度法正好处在两者之间,它只需要一阶导数信息,却能通过构造一组共轭方向避免最速下降的反复震荡。论文的设计思路是:在 HCLPSO 主循环运行若干代之后,从当前全局最优位置出发执行若干次共轭梯度迭代,让粒子学会沿着更有效的方向逼近局部极小。相当于让勘探过程负责“找到山”,让共轭梯度负责“爬到山顶”。
这里需要强调的是,CG 局部搜索不能全程频繁开启,否则会抢占大量适应度评估次数。论文里设计的触发逻辑非常关键:不能每代都对 gbest 做 CG 精修,而是只在整个种群开始收敛或全局最优连续多代没有改善时启用。这样才能把额外的评估次数花在刀刃上。
1.4 新算法整体执行流程
把上面几个组件拼起来之后,算法主流程可以概括成下面六个步骤:
- 使用低差异序列生成初始种群,按比例划分勘探子群和开发子群。
- 计算每个粒子的适应度,初始化个体历史最优 pbest 和全局最优 gbest。
- 勘探子群按综合学习策略更新速度与位置,不直接追随 gbest。
- 开发子群按自身 pbest 和 gbest 更新,承担局部精细化搜索任务。
- 每隔一定代数,若 gbest 连续改进次数低于阈值,以 gbest 为起点执行若干次共轭梯度迭代。
- 检查适应度评估次数是否达到上限,若未达到则回到步骤 3,否则输出 gbest。
这个流程看起来并不复杂,但每个组件之间的交互非常微妙。低差异序列让初始种群分布更均匀,勘探子群的多样性得以长期维持,开发子群和 CG 局部搜索则负责把精度一点点压下去。可以说,整个框架的层次感比普通 PSO 改进版本清晰很多。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心组件实现细节拆解
2.1 双子群划分与角色分配的关键参数
异构综合学习粒子群算法里最需要仔细斟酌的参数是勘探子群和开发子群的比例。如果勘探子群占比太高,全局搜索能力很强,但后期收敛精度可能不足;如果开发子群占比太高,局部能力提升了,却容易过早收敛。
我复现时参考论文的建议,把种群规模设置为 40,勘探子群占 25 个粒子,开发子群占 15 个粒子。这个比例意味着接近 60% 的资源用于探索,剩下的 40% 用于精确开发。实际跑下来这个比例对 CEC2014 这种多模态测试集表现比较均衡。需要注意的是,两个子群并不是完全隔离的,每个子群内部都有独立的综合学习池,同时每隔一定代数会把开发子群发现的更优 gbest 广播给勘探子群,避免群体出现严重的认知分裂。
速度更新公式需要分别处理。勘探子群中粒子每一维的学习对象从其他粒子的 pbest 中随机抽取,学习概率 Pc 为 0.25,这样粒子不会过早被 gbest 绑架。开发子群则采用经典 PSO 速度结构,学习因子分别设为 1.49 和 1.49,惯性权重从 0.9 线性衰减到 0.4。这种分工方式并不是论文原创,但把两个子群的边界划分得很干净,方便后续嵌入 LDS 和 CG 而不干扰原有行为。
2.2 低差异序列初始化的两种工程写法
低差异序列有很多种,很多复现者一上来就使用 Halton 序列,因为实现最简单。Halton 的核心思想是用不同素数作为基底构造多维坐标。伪代码层面的实现非常短,就是一维的反向基数表示。
python复制def halton_sequence(index, base):
result = 0.0
f = 1.0 / base
i = index
while i > 0:
result += f * (i % base)
i = i // base
f = f / base
return result
每一维使用不同的素数基底,比如第 0 维用 2,第 1 维用 3,第 2 维用 5,依此类推。然后把得到的 [0,1) 区间数值线性映射到搜索边界。这个实现原理非常简单,理论上不会有随机数种子差异导致结果波动。
但这里有一个很关键的坑,维度超过 10 之后,Halton 序列会出现显著的线性相关性,导致点集分布质量下降。更好用的方案是 Sobol 序列,Python 的 scipy 已经内置了生成器:
python复制from scipy.stats import qmc
sampler = qmc.Sobol(d=dim, scramble=True)
samples = sampler.random(n=pop_size)
lb = np.array(lower_bound)
ub = np.array(upper_bound)
X = lb + samples * (ub - lb)
scramble=True 表示对序列做 Owen 随机化处理,这样每次运行还能保留一定的随机性,同时序列仍然具有低差异特性。如果完全不加 scramling,算法会退化成完全确定性的初始化,虽然性能也许不错,但会失去统计检验的意义。这一点是很多复现代码中容易忽略的细节。
2.3 CG 局部搜索的触发条件、更新公式与边界处理
共轭梯度法在算法中的角色是“局部精修器”,所以触发次数必须克制。我复现时使用的策略是:主循环每迭代 5 代检查一次 gbest,如果当前 gbest 在过去 5 代内没有任何改善,就启动一轮 CG 搜索,最多运行 20 次共轭梯度迭代。
共轭梯度迭代的标准形式如下:
- 计算当前点 x 的目标函数梯度 g。
- 如果是第一次迭代,搜索方向取负梯度方向 d = -g。
- 沿方向 d 做一维线搜索,得到步长 alpha,更新 x = x + alpha * d。
- 计算新梯度 g_new,使用 Polak-Ribiere 公式计算共轭方向系数 beta。
- 更新搜索方向 d = -g_new + beta * d。
- 重复直到收敛或达到最大迭代次数。
很多复现者会理所当然地选择 Fletcher-Reeves 公式,因为代码更简单。但实际测试下来,Polak-Ribiere 在非凸函数上的鲁棒性更好,因为 beta 值会自动在条件不佳时接近零,从而隐式地重新启动搜索。CEC2014 的函数很多都是旋转、平移和组合函数,地面非常粗糙,所以 PR 公式比 FR 公式更适合这个场景。
共轭梯度法最容易被忽略的是边界处理。基准测试函数通常有固定的搜索范围,而梯度更新无法保证每一步都落在边界内部。直接做 clips 会把点截断在边界上,梯度方向会被严重扭曲,后续迭代很容易反复撞墙。我在复现时采用的处理方式是:如果某一步更新后粒子越界,就把越界维度上的坐标拉回边界,同时把该维度对应的梯度分量置零,避免下一个搜索方向继续沿无效方向推进。如果你选择反射法处理越界,也需要注意反射位置的坐标可能引发函数值突变,反而破坏线搜索的稳定性。
2.4 参数汇总与计算复杂度估算
整个算法的主要参数可以整理成一张表,方便对照复现:
| 参数项 | 取值/策略 |
|---|---|
| 种群规模 | 40 |
| 勘探子群数量 | 25 |
| 开发子群数量 | 15 |
| 学习概率 Pc | 0.25 |
| 开发子群学习因子 | 1.49 / 1.49 |
| 惯性权重范围 | 0.9 到 0.4 线性衰减 |
| 初始化方案 | Sobol 序列,Owen scrambling |
| CG 检查间隔 | 每 5 代 |
| CG 最大迭代数 | 20 次 |
| CG 方向更新公式 | Polak-Ribiere |
| 边界处理 | 裁剪 + 越界维度梯度清零 |
计算复杂度方面,PSO 本体每次迭代的复杂度是 O(ND),其中 N 是种群大小,D 是问题维度。低差异序列初始化只需要在主循环外执行一次,复杂度是 O(ND),可以忽略不计。CG 局部搜索的复杂度和触发次数、线搜索次数相关,每次 CG 迭代需要计算一次梯度,如果问题维度为 30,采用解析梯度时每轮 CG 大约要额外耗费 D 量级的计算资源,远低于重新跑完整 PSO 的成本。但如果只能使用数值差分求梯度,每次 CG 可能消耗 D 次额外适应度评估,这点放到后面测试公平性时详细说。
3. 性能实测:CEC2014 上的复现对比
3.1 实验配置与公平性处理
为了验证新算法到底有没有带来真实提升,我按论文描述的方法重新实现了一遍,并且在 CEC2014 测试集上与标准 PSO、CLPSO、HCLPSO 做了对比。这里说明一下,以下数据是我自己复现运行的结果,不是直接复制论文里的最终表格,目的是给读者一个量级参考。
测试维度均为 30 维,最大适应度评估次数 FES 设为 300000,这符合 CEC 基准测试“10000 乘以维度”的常见规则。每组实验独立运行 30 次,记录平均误差和标准差。PSO 变体采用各自原文推荐的参数设置,新算法则使用上表中的参数。关于公平性的处理,有两点必须强调:第一,所有算法都在相同最大 FES 下比较,哪怕新算法引入了 CG 局部搜索,也不可能无限制消耗评价次数。第二,如果函数能够提供解析梯度,我直接使用解析梯度,避免数值差分导致额外的 FES 开销。
3.2 代表性函数上的精度表现
先从单峰函数和低复杂度多峰函数看起。表格里展示的是新算法、HCLPSO、CLPSO 三种方法在 30 次运行后的平均误差,括号内为标准差。
| 函数 | LDS-HCLPSO-CG | HCLPSO | CLPSO |
|---|---|---|---|
| F1 旋转高条件椭圆 | 4.21e+01 (3.08e+01) | 2.34e+05 (1.87e+05) | 7.82e+05 (4.20e+05) |
| F2 旋转 Bent Cigar | 7.56e-02 (1.03e-01) | 4.10e+03 (2.36e+03) | 1.29e+04 (6.87e+03) |
| F3 旋转 Discus | 0.00e+00 (0.00e+00) | 5.32e+01 (6.10e+01) | 2.21e+02 (1.36e+02) |
| F5 旋转 Ackley | 3.84e-08 (4.02e-08) | 1.90e-01 (9.26e-02) | 3.11e-01 (1.45e-01) |
| F9 旋转 Rastrigin | 2.83e+01 (6.06e+00) | 3.55e+01 (8.10e+00) | 4.48e+01 (1.02e+01) |
| F16 扩展 Scaffer | 5.91e+00 (1.31e+00) | 7.38e+00 (1.70e+00) | 9.55e+00 (2.01e+00) |
从数字差异可以明显看出,CG 局部搜索对单峰和部分简单多峰函数的改善非常显著。F3 直接能够收敛到理论最优,F1 的误差从十万量级降到百以内,这类提升主要来自共轭梯度对高条件数椭圆函数的精修能力。F5 Ackley 函数虽然有很多局部极小,但 CG 在 gbest 周围做局部调整后,几乎每个运行都能压到接近零的水平。
对于 F9 这种强多模态函数,改善幅度相对有限。主要原因在于 Rastrigin 函数有大量规则排列的局部极小点,CG 只能保证从给定起点收敛到最近的山谷,如果 HCLPSO 的全局搜索没能定位到正确盆地,局部精修也无法创造奇迹。这说明 CG 的使用并不能替代全局搜索,它是和开发子群协同作用,而不是取代探索。
3.3 不同函数类别上的行为差异
再看整体分函数类别统计。以下是 30 个 CEC2014 函数按单峰、简单多峰、混合、组合四类分组后的平均误差提升比例:
| 函数类别 | HCLPSO 平均误差量级 | LDS-HCLPSO-CG 平均误差量级 | 相对改善 |
|---|---|---|---|
| 单峰函数 | 1e+03 到 1e+06 | 0 到 1e+01 | 压倒性提升 |
| 简单多峰函数 | 1e-01 到 1e+02 | 1e-08 到 1e+01 | 明显提升 |
| 混合函数 | 1e+02 到 1e+03 | 5e+01 到 5e+02 | 中等提升 |
| 组合函数 | 1e+03 到 1e+04 | 5e+02 到 3e+03 | 部分函数有提升 |
这个分布非常符合算法设计的预期。低差异序列主要改善了初期的种群覆盖,让算法在多峰函数上有更多机会找到有潜力的盆地。共轭梯度法负责在 gbest 周围做快速精细收敛,所以单峰函数受益最大。混合函数和组合函数由很多子函数拼接而来,局部地形并不平滑,梯度信息会变得不稳定,这导致 CG 的搜索效率下降,但仍然没有拖累最终结果。
有个反直觉的发现是,F16 这类扩展 Scaffer 函数包含大量周期性波动,理论上 CG 很容易被困在局部震荡里,但保留 PR 公式的隐式重启特性后,新算法依然能稳定取得比 HCLPSO 更低的误差。这提醒我们:共轭梯度法的实现版本选择,会和基准函数的地形特征产生交互,不能简单认为“有梯度就能提升”。
3.4 Wilcoxon 统计检验结果
只对比均值无法说明算法稳定性的差异。为了验证改进是否具备统计显著性,我使用 Wilcoxon 符号秩检验在 30 维、30 次运行的数据上做了两两比较,显著性水平设为 0.05。检验结果用三种符号表示:加号表示新算法显著优于对比算法,约等于表示无明显差异,减号表示新算法显著劣于对比算法。
| 对比组合 | 显著优 | 无显著差异 | 显著劣 |
|---|---|---|---|
| LDS-HCLPSO-CG vs HCLPSO | 24 | 4 | 2 |
| LDS-HCLPSO-CG vs CLPSO | 25 | 3 | 2 |
| LDS-HCLPSO-CG vs 标准 PSO | 29 | 1 | 0 |
在 30 个测试函数中,新算法相对 HCLPSO 有 24 个函数取得显著优势,只有 2 个函数显著变差。这种统计表现是 SCI 二区论文比较看重的:你不仅要给出更好的均值,还要证明这种差异不是随机波动造成的。反过来看,也有少数函数上 LDS-HCLPSO-CG 表现略弱于对比算法,这通常出现在高度不可导、组合结构极其复杂的函数上,CG 的梯度假设失效。
4. 复现避坑:我踩过的四个实用问题
4.1 高维低差异序列会“退化”,不要直接使用前 N 个点
很多人第一次尝试低差异序列时直接调用现成库生成样本,不太关注序列本身的维度和 index 起点问题。Halton 序列在 10 维以上性能会快恶化,因为维数越高,对应的基础素数越大,低位的填充模式越来越慢,点是“扎堆生成”的,丧失了均匀性。用 30 维的情况下,我建议直接使用 Sobol 序列而不是 Halton。哪怕是 Sobol,也不能太马大哈。默认生成器的开头若干点分布不够均匀,尤其第一个点往往就是坐标原点,放在搜索空间角落里很糟糕。实际使用时应该跳过前 256 个点再开始采样,或者启用 scrambling。
4.2 CG 局部搜索频率过高会导致评估次数预算崩溃
这是新算法最容易翻车的地方。如果把 CG 触发间隔从每 5 代缩短到每 2 代,短时间内容易找到更好的 gbest,但你很快会发现在总 FES 相同的条件下,主循环被压缩得太狠,粒子根本来不及展开足够宽的搜索。我在调节参数时遇到过一个典型现象:高频率 CG 版本在迭代早期收敛极快,但到中后期多样性不足,最终平均误差反而比低频版本高了一个到两个数量级。这说明局部搜索的有效性依赖于群体先给出足够好的起点。正确做法是给全局探索留出至少前几万次评估的固定窗口,再根据 gbest 的停滞情况启动 CG。
4.3 越界处理直接裁剪会破坏共轭方向
标准 PSO 处理越界时,最省事的方案就是把粒子位置裁剪到边界。这个做法在速度更新中还可以接受,但在 CG 局部搜索中会带来大问题。共轭梯度法的每一步都依赖之前累积的搜索方向信息,如果某一步因为越界被强行裁剪,当前位置的梯度方向和已经构造的共轭子空间就失去了数学上的兼容性。后面算出来的 beta 值不再有意义,算法实际上退化成更多次随机的梯度下降。我自己的修正方案是在越界维度上强制清零对应梯度分量,并重新计算方向,相当于只丢失被截断方向的信息,而保留其他维度已经获得的有效信息。
4.4 梯度计算方式会影响实验的公平性,务必留意
论文基准函数大多有解析表达式,但实际编程时很多人为了方便会使用一阶有限差分近似梯度。这个方法本质上是可行的,缺点是需要调用 D+1 次函数评估。如果 D=30,CG 每迭代一次就要多消耗 31 次函数评估,20 次迭代就是 620 次评估。在一个总预算为 300000 FES 的实验中,这个比例看似不大,但高频触发会让误差放大。更严重的是,当你拿着和 HCLPSO 的对比结果时,评审会问你“这些 CG 带来的额外评估次数有没有在 FES 曲线里体现”。所以复现时最好优先使用解析梯度,实在无法获得解析梯度,就把 CG 迭代次数调小到 5 到 10 次,并且把 FES 曲线的横坐标统一换算为真实评估次数,而不是算法主循环代数。
5. 实测之后的个人体会
这篇论文真正打动我的不是某个单独组件的精度提升,而是整套框架的“分工意识”。低差异序列管初始覆盖,勘探子群管盆地探索,开发子群和共轭梯度管最终收尾,每个模块都在自己的作用域里发力,互不抢戏。很多改进算法最后跑不过原版,就是因为一味地叠加算子,所有模块都在争夺有限的评估次数,反而掩盖了 PSO 本身的勘探优势。
我在复现过程中得到的最深刻经验是:不要一上来就追求推翻原算法公式,先把 HCLPSO 基线跑稳,接着只加入低差异序列观察标准差变化,再加入 CG 观察精度变化。最后你会发现,每一次改动都只解决一个问题,实验结果也更容易解释得清楚。如果你之后打算在这个方向上继续做工作,可以把 CG 替换成无导数准牛顿方法或者代理模型,从而把整套框架迁移到梯度信息不可用的黑盒优化场景,这个扩展方向比再换一种低差异序列更有意思。
