☰
无人机三维航迹规划中改进动态多种群粒子群算法实战
2026/10/20 22:19:36 网站建设 项目流程

做无人机三维路径规划,最让人头疼的不是地形建模,而是算法一收敛就再也跳不出来。我第一版用的是标准粒子群算法,20个粒子跑300代,结果每次都在同一条绕远、贴着威胁区飞过的路径上反复收敛,看起来算法很努力,实际上一点改进都没有。后来把单种群改成动态多种群,配合自适应迁移和停滞扰动,才把航迹质量拉起来。

这篇文章把我从标准PSO切到改进动态多种群粒子群算法(IDMSPSO)的全过程整理出来,重点说清楚机制为什么有效、三维代价函数怎么建、MATLAB里怎么落地,最后放一组可视化的效果对比。如果你正在复现这类论文,或者被航迹规划中的早熟问题困住了,这篇应该能省你不少时间。

1. 为什么标准PSO在三维航迹规划里总在"假收敛"

1.1 三维航迹规划到底在解一个什么问题

先明确任务本身:给定一块数字高程地形,若干个威胁区(雷达站、防空火力、禁飞区域),以及起点和终点坐标,算法要生成一条从起点到终点的连续可飞轨迹。所谓"可飞",通常包含几个硬性要求:

  • 轨迹不穿越地形,且保持一定的最低离地高度。
  • 轨迹不能穿过威胁区,最好还要留出安全裕度。
  • 相邻路径段之间的转弯角不能过大,否则无人机物理上拐不过来。
  • 整条轨迹尽量短,同时飞行高度尽量平稳,减少油耗和暴露风险。

在粒子群算法里,"解"一般表达为一串路径点。比如设置10个中间点,每个点有x、y、z三个坐标,粒子维度就是30。起点和终点固定,算法只优化中间点的位置,最后把点连起来再插值成平滑轨迹。这个问题往深了说是个多约束、多峰值的三维优化问题,地形起伏意味着代价函数表面密密麻麻全是局部极值。标准PSO在这种地形上特别容易出问题。

1.2 标准PSO的"随大流"陷阱

标准粒子群的速度更新公式大家都熟:

v = w*v + c1*r1*(pbest - x) + c2*r2*(gbest - x) x = x + v

核心问题在于最后一项,全局最优gbest每代都在把整个种群往自己那边拽。单种群结构下,只要gbest落进一个局部最优,其他粒子很快也会被拽过去,种群的多样性随之急剧下降。到迭代后期,粒子间距越来越小,速度趋于0,算法看起来在收敛,实际上只是在局部位置来回抖动,根本没有继续搜索新区域的能力。

我做过一个简单的观测:30维航迹规划问题里,标准PSO从第40代左右开始,种群的平均速度就掉到了初始阶段的10%以下。你能看到适应度曲线还在缓慢下降,但下降幅度越来越小,最后完全停住。这不是收敛,是"假收敛"——算法自以为找到了答案,实际上是困在了一个劣质局部解里。

可以打一个比方:标准PSO就像公司开会,领导定了调子,下面的人很快全跟着点头,会上气氛热烈,但没有人愿意提出真正不同的方案。多种群策略不一样,它更像把一群人分成几个独立小组先各自讨论,过一会儿再把各组的结论互通有无。这样即使某一组讨论方向错了,其他组还有机会拿出更好的方案。

1.3 为什么这类题目都喜欢动粒子群算法

粒子群算法本身结构简单、参数少、代码容易写,而且每一步更新都有明确的物理直觉可讲。相比遗传算法那套选择、交叉、变异,粒子群的"个体经验+社会经验"框架更适合在基础上叠加机制创新。这也是为什么改进粒子群的论文在路径规划领域特别多。

但我要说句实在话:很多改进属于堆机制,加了这个算子加那个算子,最后收敛了,却说不清楚到底是哪个机制起的作用。真正有效的改进,往往都围绕两个核心矛盾展开:一是"探索与开发"的平衡,二是"种群多样性保持"。动态多种群策略恰好同时打在两个点上:通过分组制造信息孤岛,保留多样性;通过迁移和扰动,让好信息在合适的时机扩散。理解了这个逻辑,你再看下面的设计细节就不会觉得它是一堆花哨操作的堆砌了。

2. 动态多种群机制:把信息孤岛变成有序竞争

2.1 为什么要先把种群拆散

在单种群PSO里,信息传播速度太快。任何一个粒子发现了一个还不错的位置,全局最优马上更新,所有粒子都朝那个方向奔。如果这个位置只是局部稍好,整个群体就被带偏了。

拆成多个子种群之后,每个子种群有自己独立的gbest,信息默认只在小圈子内部传播。这意味着不同子种群可以并行探索不同的山沟——有的专注于低海拔快速航线,有的专注于绕开威胁区的安全航线,有的尝试爬升高度换取更短的水平距离。一段时间内大家互不干扰,各自积累"小范围最优经验"。

但完全隔离也不行。不然就成了多个标准PSO各跑各的,每个都在局部最优里打转。所以必须有一种机制,每隔若干代让子种群之间交换信息,把某一组发现的优质路径点坐标"移民"到其他组。这个交换机制在多种群算法里一般叫迁移或移民算子。

2.2 三个关键改进:动态重组、自适应迁移、停滞扰动

下面是我在这套IDMSPSO里实际采用的三个核心机制,也是它跟"固定多种群PSO"的本质区别。

第一个:动态重组。固定多种群的问题在于分组一旦确定,整轮迭代不会变。如果一个子种群能力弱、位置差,它可能整轮都在拖后腿。我的做法是每隔一定代数,计算各子种群最优代价的方差。如果这个方差很小,说明子种群之间已经趋于一致,多样性正在流失。这时候触发重组:把全部粒子打乱,按照当前适应度重新均匀分配到各子种群,确保每个子群里既有好粒子也有差粒子。如果方差还很大,说明各组还在探索不同区域,就保持现有分组不动。

第二个:自适应迁移。迁移不能是固定周期的"每10代迁移一次",那样太机械。前期种群多样性充足,各子群应该少交流,多独立探索;后期多样性下降,才需要增加信息交流。我用的是:迁移间隔从30代逐渐缩短到10代,迁入率从1个粒子逐渐增加到3个粒子。效果是前期避免过早趋同,后期加快优质解的传播和精细搜索。

第三个:停滞扰动。迁移解决的是组间信息交换,但还没有解决"全组陷入局部最优"的问题。我增加了一个检测:如果某个子种群的全局最优连续15代没有任何改进,就在该组最优粒子的速度向量上叠加一个混沌扰动,然后把组内最差的3个粒子重新随机初始化。混沌扰动比高斯扰动更有优势,它不会重复同一个方向,搜索路径更随机。这样一来,停滞的组被强制"踹一脚",有更大概率跳出局部最优。

这三个机制不冲突:动态重组管结构,自适应迁移管信息流通,停滞扰动管局部救火。它们共同维持着多样性与收敛速度之间的平衡。

2.3 动态调整到底调整了什么

很多人理解多种群,以为只是"多跑几组PSO然后取最优"。真正的动态调整体现在三个层面:

  • 结构层面:子种群的组成随迭代动态变化,不固定。
  • 信息层面:迁移的频率和规模随搜索阶段自适应变化。
  • 个体层面:停滞粒子被重新初始化,种群活力持续恢复。

标准PSO里的惯性权重w也可以随时间从0.9线性降到0.4,那是参数层面的动态。而多种群机制是在算法结构层面做动态,信息传播的拓扑结构本身在变。这一步改进带来的多样性收益,比单纯调w大得多。从实验结果看,同样是在30维航迹规划问题上,标准PSO通常跑到60代以后就没动静了,而IDMSPSO到150代还能出现明显的代价下降。

3. 三维环境建模与航迹代价函数:决定算法上限

3.1 地形与威胁区怎么送进算法

环境建模在整个流程里属于"差之毫厘谬以千里"的环节。地形我用的是栅格化的数字高程模型(DEM),就是一个矩阵,每个格子存一个高度值。粒子在搜索过程中产生的路径点坐标是连续值,不一定正好落在栅格点上,所以要插值取高度。MATLAB里直接用interp2:

% demX, demY 是栅格坐标网格,demZ 是高度矩阵 h = interp2(demX, demY, demZ, xq, yq, 'linear');

这里有个很容易踩的坑,后面专门讲。威胁区我用圆柱模型来表示,每个威胁区有中心坐标、半径和有效高度。评估路径代价时,只要路径点落在圆柱范围内,就累加威胁代价。

3.2 航迹代价函数由哪几项组成

航迹代价直接决定算法"认为什么样的路径是好路径"。我这边用的是四项加权和:

总代价 = w1*路径长度代价 + w2*威胁代价 + w3*高度代价 + w4*平滑代价

路径长度代价就是相邻路径点之间的欧氏距离之和,代表飞行距离和油耗。威胁代价的计算思路是:对每个路径点,计算到每个威胁区中心的水平距离。如果距离小于威胁半径,代价按超出部分累加,而且是平方项。这样做的好处是,粒子越深入威胁区,惩罚越重,算法会被梯度"推"出威胁范围。

高度代价包含两层:一是路径点距离地表的离地高度要控制在合理区间,太高则油耗大且暴露风险高,太低则容易撞山;二是路径整体不要出现剧烈起伏。平滑代价计算相邻路径段之间的夹角,所有夹角平方后求和。夹角越大,代价越大,这样算法就不会生成折线锯齿状的"纸面飞线"。

权重设置很重要,因为各项是不同量纲的:路径长度可能是几十米量级,威胁代价是面积概念,平滑代价是角度量级。不归一化直接加权,某一项会完全支配其他项。我的做法是先跑几轮基准实验,看各项的数值分布,然后根据优先级设定权重比例。比如让我优先保证安全,就把威胁代价权重拉高。

3.3 约束处理的实操方式

三维路径规划里的约束分两类。硬约束,比如路径不能穿地、不能越界,我的处理是直接修正到边界上,不让违反约束的个体存活;软约束,比如威胁区规避、转弯角限制,放进代价函数里做惩罚。

核心代价函数可以写成类似这样:

function cost = pathCost(pts, dem, threats, weights) % pts: Nx3 的航迹点序列 % 路径长度代价 diffVec = diff(pts); segLen = sqrt(sum(diffVec.^2, 2)); lenCost = sum(segLen); % 威胁代价 threatCost = 0; for k = 1:size(threats, 1) dist = sqrt((pts(:,1)-threats(k,1)).^2 + ... (pts(:,2)-threats(k,2)).^2); over = max(0, threats(k,3) - dist); threatCost = threatCost + sum(over.^2); end % 平滑代价:计算相邻段夹角 v1 = diffVec(1:end-1, :); v2 = diffVec(2:end, :); cosAngles = sum(v1.*v2, 2) ./ (vecnorm(v1,2,2).*vecnorm(v2,2,2)+eps); angles = acos(max(-1, min(1, cosAngles))); smoothCost = sum(angles.^2); cost = weights(1)*lenCost + weights(2)*threatCost + ... weights(3)*smoothCost; end

注意acos那里的数值保护:浮点运算可能导致cosAngles略大于1或略小于-1,不加截断直接acos会得到NaN,整个粒子代价就废了。这种小细节论文里不会写,但代码里不处理就是一天的事故现场。

4. MATLAB实现:数据结构、主循环与可视化

4.1 粒子编码与数据结构设计

粒子编码方式直接影响算法效果。我采用的是:一个粒子的位置向量是1×D行向量,D=3×Npts,Npts是中间路径点个数。前Npts个元素是x坐标,中间Npts个是y坐标,最后Npts个是z坐标。编码展开之后直接用单层for循环更新就可以。

MATLAB里我用结构体数组存粒子信息:

particles(i).pos % 当前位置,1xD particles(i).vel % 当前速度,1xD particles(i).pbest % 个体最优位置 particles(i).cost % 当前代价 particles(i).bestCost % 个体最优代价

每个子种群单独维护一个groupBest位置和代价。用结构体虽然比纯矩阵慢一点,但代码可读性好太多,调参和扩展机制都方便。真需要性能优化时再改mex或者转成矩阵运算,前期没必要。

初始化时,不采用全随机,而是让粒子从"起点到终点的直线附近"随机偏离。这样初始种群整体代价不高,收敛更快。具体做法是把直线路径作为均值,加一个随迭代次数逐渐缩小的正态扰动。一开始扰动幅度大,保证覆盖空间;后期幅度小,保证局部精细搜索。

4.2 主循环与动态机制的程序骨架

主循环结构用伪代码表达很清楚:

for it = 1:MaxIter for s = 1:nSub idx = subParticles{s}; % 每个子种群内部进行标准粒子群更新 for i = idx update_velocity(i); update_position(i); bound_check(i); eval_cost(i); update_pbest(i); end update_groupBest(s); end % 动态重组:每ReorganGap代判定一次 if mod(it, ReorganGap) == 0 diversity = std([groupBest.cost]); if diversity < threshold reinit_grouping(); end end % 自适应迁移 if mod(it, migrationGap(it)) == 0 ring_migration(); end % 停滞扰动 for s = 1:nSub if it - groupBest(s).lastUpdate > stallLimit chaos_perturb(s); end end end

自适应迁移的环形结构值得说一下:把子种群编号看成一个环,1号迁到2号,2号迁到3号,最后一个迁到1号。每个子种群把自己组内最优粒子的位置拷贝一份,替换目标组内最差粒子的位置,同时把该粒子的速度重置为0。环形迁移的好处是每个组只接收一次外部信息,不会出现"两个组同时被同一个强组覆盖"的羊群效应。

4.3 三维可视化:除了画线还要会看图

MATLAB里地形可视化我用的是surf,航迹用plot3,威胁区用圆柱体图形对象。关键是坐标轴比例要一致,不然地形会看起来被压扁或拉伸,判断路径是否绕开威胁区时会产生错觉。

surf(demX, demY, demZ, 'EdgeColor', 'none', 'FaceAlpha', 0.8); hold on; plot3(traj(:,1), traj(:,2), traj(:,3), 'r-', 'LineWidth', 2); plot3(traj(:,1), traj(:,2), traj(:,3), 'ro', 'MarkerSize', 5);

除了显示原始路径,我最后还会对最优航迹做一次三次样条平滑处理,用MATLAB的csaps做平滑,光顺系数取0.4左右。平滑之后的路径代价会重新评估一次,你会发现代价甚至比原始路径还低,因为原始路径上的锯齿状小转弯被拉直了。这也是很多论文里"效果展示图"看起来非常漂亮的一个幕后操作——图里画的是后处理轨迹,不是算法直接输出的折线。

可视化这块还有一个实用技巧:把每次迭代的种群最优代价保存下来,画成收敛曲线。曲线配合三维路径图一起展示,才能同时说明"算法确实在收敛"和"收敛出来的轨迹是合理的"。

5. 实验设置与效果对比:改进到底改进了多少

5.1 我的测试场景与算法参数

测试场景不大,但足够说明问题:地图范围200米×200米,DEM栅格分辨率1米,也就是201×201的高度矩阵。设了三个威胁区,分布在中段和后半段附近,把从起点到终点的大部分直线路径都挡住了。起点在左下角,终点在右上角,直线距离大约283米。

算法参数上,我做了对照实验。标准PSO:种群100个粒子,迭代300次。IDMSPSO:分成5个子种群,每个子种群20个粒子,总粒子数同样是100,迭代次数同样是300。这样对照才公平——不能为了突出改进算法,就让标准PSO少算几步。

具体参数大概是这样:

参数标准PSOIDMSPSO
子种群数15
每群粒子数10020
总粒子数100100
迭代次数300300
惯性权重w0.9→0.40.9→0.4
迁移间隔无30代→10代自适应
停滞检测代次无15代
动态重组阈值无自适应

5.2 收敛过程与航迹指标对比

在我这边的测试场景里,标准PSO的最佳代价最终停在212.6,而IDMSPSO最终代价降到了167.3。差距不算夸张,但看细节就有意思了:标准PSO从第35代开始,代际代价改善小于0.5%的情况持续了几乎200代;IDMSPSO在全程300代里,出现过两次明显的"阶梯式下降"——一次在90代附近,一次在210代附近。这两次下降分别对应停滞扰动把某个子种群从局部最优里推出来,以及迁移把另一组的优质路径信息扩散开。

路径指标上的差异更直观:

指标标准PSOIDMSPSO
路径总长度296.3m271.8m
最大威胁穿透深度6.2m0m
最大转弯角41°23°
最大离地高度63.4m48.1m
迭代300次后代价212.6167.3

标准PSO给出的路径虽然总长度不算特别离谱,但它有一小段直接插进了威胁区边缘,而且是硬生生切过去的急转弯,这种路径在工程上根本不能飞。IDMSPSO的路径完整避开了三个威胁区,转弯角也控制得很平滑。这就是"表面收敛"和"真正收敛"的区别。

5.3 从三维效果图里能看到什么

可视化效果图是最直观的验收工具。把两条轨迹同时画在地形上,标准PSO的轨迹会在第一个威胁区附近出现明显绕行,但绕行的方式是外抛一个大弧线,浪费大量距离,还在中途突然拉高再俯冲。IDMSPSO则是在接近威胁区前提前切向侧面,高度变化平缓,整体像一条有经验的飞行员飞出来的路线。

我做了一个gif动图,把最优航迹逐代叠加显示,可以看到标准PSO在前期快速找到一条"还凑合"的路径之后,后面几乎所有迭代都在这条路径附近小幅抖动;而IDMSPSO中段和后期会突然出现一条全新的、完全不同形状的航迹,然后迅速成为新的最优。这就是子种群没有被主流信息绑架的直观证据。

6. 容易被忽略的细节:调试心得与参数血泪

6.1 地形插值方向与网格坐标顺序

我在前面提到这是一个坑,具体是这样的:MATLAB的meshgrid生成坐标网格时,X矩阵是按行横向变化的,Y矩阵按列纵向变化。如果从别处导入DEM数据后,没有把矩阵转置就直接和interp2的坐标网格对齐,地形看起来就会沿对角线翻转。

更隐蔽的问题是经纬度坐标或投影坐标的x、y范围和矩阵行列索引的顺序颠倒。我曾经在某个地形数据上跑出来的最优路径,看起来完美避开了所有威胁区,后来单独检查才知道,它实际上是在"地图转置"后的假地形里飞的,一旦回到真实坐标系,路径直接穿透地形。从那以后我养成一个习惯:每次加载地形,先画一次等高线图人工核对起点终点位置,再开算法跑。

6.2 迁移周期、子群规模的敏感性

迁移周期太短会让各子群迅速同质化,多种群的优势荡然无存;太长则信息共享不足,后期收敛偏慢。在我这个场景里,30代到10代的自适应方案效果最好;固定20代迁移会略差但差别不大;固定5代迁移则明显恶化,最终代价甚至会超过标准PSO。

子种群数量我试过3、4、5、8。3个组时多样性不够,8个组时每组只有10来个粒子,局部搜索能力太弱,结果也不理想。5个组每组20粒子是我这个场景的甜点,但注意这是维度30左右的情况,如果你的路径点多、问题维度上百,每组粒子数要相应增加。

6.3 复现这类算法的一个主要建议

如果你打算从标准PSO切到多种群方案,不要三个机制一起上。我的流程是:第一步先跑标准PSO拿到baseline;第二步只加"固定多种群+固定周期迁移",跑通看效果;第三步加自适应迁移;第四步再上停滞扰动。每一步都保留当时的三维轨迹图、收敛曲线和参数记录,这样出了问题你至少知道是哪个环节引起的。

还有个细节,迁移操作要避免把最优个体直接覆盖到目标组的最差个体上。直接覆盖会丢失目标组已有的弱个体,而弱个体有时候会在后续迭代中突变出意想不到的好解。比较稳妥的做法是让被迁入的粒子只作为该组的一个普通粒子参与更新,同时保留原有的最差粒子,只是降低它的社会学习权重。这种"软迁移"的做法,在多种群PSO文献里也有提到。

最后再分享一个小技巧:把每次实验的收敛曲线和最优代价自动保存到文件,文件名带上参数组合的编号。调参调多了会发现,能够帮你复原"上一次那个效果更好的参数"的,就是你当时随手存的这套记录。很多人复现论文改来改去最后忘了哪组参数最好,原因就是没有做系统化的实验记录。路径规划这个方向,好效果往往不是突然跑出来的,而是从一次次有记录的试错里堆出来的。

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

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

立即咨询