做无人机路径规划这题我在2025年年初又捡起来做了一遍这次优化器的选型换成了穿山甲优化算法CPO全称Crested Porcupine Optimizer在交流中也有人叫穿山甲算法。项目内容不复杂用CPO在三维障碍环境中帮无人机规划一条从起点到终点的可飞路径Matlab从建模到出图完整实现了一遍算是把路线、约束、代价函数、参数调优全部打通的一个复盘式记录。如果你正打算用群体智能算法做路径规划或者单纯想把CPO从论文搬进工程代码里这篇文章应该能直接拿来抄作业。先交代清楚这篇东西要解决什么问题无人机路径规划本质上是在给定起点、终点和非安全区域后找一条长度合理、够平滑、不离谱的飞行轨迹。传统方法比如人工势场容易陷进局部极小A*这类搜索算法在连续三维空间里很难处理好高维连续解空间。这两年开始加入智能优化算法的组合打得很常见穿山甲算法是比较新的一类启发式方法参数少、收敛快尤其适合在中等规模地图上做离线航迹规划。我把整个项目从算法拆解、问题建模到Matlab代码细节、参数调试、常见坑位都整理在下面涉及的关键词有CPO、无人机路径规划、Matlab实现、代价函数、避障约束。1. 项目背景为什么2025年还要用CPO算法做路径规划无人机路径规划这个方向看着老实际越做越细。以前大家关心的是能不能找到一条路现在更关心找路的质量和计算代价。穿山甲优化算法在2024年、2025年这几篇新文献里表现比较突出它主要模仿穿山甲在觅食和面对天敌时的行为包括释放信息素探索、蜷缩身体旋转滚动、用鳞片掘土挖掘食物。把这些行为抽象成算法的探索和开发机制和粒子群PSO、遗传算法GA比优势主要在两个地方一是全局探索阶段带记忆和气味梯度不容易早期就抱团二是开发阶段的局部扰动步长是自适应的到了迭代后期不会像PSO那样容易陷入振荡。选择CPO而不是直接用成熟算法还有一个现实原因2025年我们项目组拿到的任务是非结构化三维环境下的航迹评估地图里障碍物不规则目标函数需要频繁改动。CPO最大的特点是算法骨架非常干净不依赖太多算子组合想在里面塞进路径长度、平滑代价、安全距离、高度限制这四类约束时只需要设计一个合适的适应度函数算法主体完全不用动。这点比遗传算法那种又要调选择方式、又要调交叉变异概率的状态要省事很多。CPO在无人机路径规划里的定位也很明确它不解决实时避障那是局部规划器的事它解决的是起飞前的全局路径规划在已知静态障碍环境下把连续航路点的坐标优化出来。项目里我们把问题抽象成一个带约束的单目标优化问题解空间就是一组航路点的坐标值维度等于中间航路点数量乘以3。仿真场景设置在100×100×50的空间起点设在底部角落终点设在对角方向中间随机生成若干圆柱体障碍物CPO要把连续路径点绕开这些障碍同时还要保证路径平滑度和高度约束。这里直接给出一个核心结论如果地图相对固定、航路点数量在10个以内CPO在200次迭代内基本能收敛到一个可用的解计算时间在普通笔记本上不到10秒。如果地图特别复杂或者要求保守解的置信度增加种群数和迭代次数可以把结果拉高一个档次但没必要一开始就把参数开得很大先小规模跑通再逐步加规模这是整个项目最省时间的一条经验。2. 穿山甲优化算法CPO核心原理与选型逻辑2.1 从穿山甲行为到算法公式探索与开发机制拆解穿山甲算法的命名已经说明了它的灵感来源。在自然界里穿山甲有三个特征行为它会用灵敏的嗅觉沿着信息素轨迹寻找蚂蚁和白蚁巢穴这是它在未知区域做大范围探测的方式遇到危险时它会把身体蜷缩成一个紧密的球同时转动鳞片来迷惑捕食者这种行为在算法里对应解空间里的局域扰动而在确定巢穴位置后它会用强壮的前爪掘开土堆挖出隧道接近猎物这是开发阶段的核心逻辑。算法实现时大致分为两个阶段。前期探索阶段每个个体的位置更新受当前最优个体和邻域随机个体共同影响同时保留一个信息素记录相当于记忆了历史搜索位置防止反复走回头路。后期开发阶段个体以当前解为中心按照随迭代次数缩小的扰动半径进行滚动式搜索如果新解更优就接受否则以一定概率保留而非彻底丢弃这样既保证了局部精细搜索又保留跳坑的可能。主循环伪代码可以写成下面这样的逻辑初始化种群位置 评估初始适应度 记录全局最优 for iter 1:MaxIter for i 1:PopNum if rand 探索概率(随迭代递减) 利用全局最优位置信息素历史做全局探索 else 以当前点为中心做蜷缩滚动扰动 向最优解方向做纵向挖掘开发 end 计算新适应度 根据贪婪规则更新个体位置 保留全局最优 end end这段结构是CPO实现上最通用的形态贴回Matlab代码时只需要把位置更新公式替换成对应的向量运算剩下的循环、边界处理、最优解追踪都可以复用我们项目里的公共框架。2.2 为什么选CPO与PSO、GA的对照分析路径规划优化算法这几年用下来我个人的体会是PSO收敛快但容易早熟障碍物一多就容易把路径压到障碍边界上看起来好像避开了实际上真实飞机根本飞不过去GA全局搜索能力不差但编码、交叉、变异三步的算子设计麻烦航路点是浮点数编码时交叉操作容易破坏已经形成的避障结构。CPO在这两者之间找了一个平衡点。做一个明确的横向对比对比维度PSOGACPO穿山甲算法参数数量惯性权重、学习因子等交叉率、变异率、种群规模等探索概率、扰动衰减系数局部开发能力中等后期收敛慢交叉算子保优能力弱滚动扰动开发步长自衰减跳出局部最优能力一般较强但随机性大信息素记录概率跳跃工程实现难度容易中等容易路径平滑性依赖适应度函数依赖交叉变异设计扰动步长连续路径更顺这张表不是否定PSO和GA而是在特定场景下的选型结论项目方要求路径规划结果可复现、代码可审计、参数调整范围要小CPO最合适当主力算法。2025年这个时间点智能算法很多论文都在炫复杂度但工程实现端更看重稳定和可控CPO的简洁在此成了最核心的竞争力。2.3 算法的收敛平衡探索与开发的相位切换穿山甲算法的一个关键控制参数是探索概率p它随着迭代次数动态衰减前期p高个体更愿意跳往地图不同区域探索后期p低群体集中在最有希望的局部区域做精细开发。项目里我设置p从0.9线性衰减到0.1对应200次迭代前80次迭代重在把航路点散布到障碍物的各个绕行缺口后120次迭代则集中打磨路径长度和平滑性。这个衰减策略比固定概率稳定得多。固定高概率会导致后期最优路径不断被新随机解扰动固定低概率则前期就陷入局部障碍区域。实测下来线性衰减的收敛曲线虽然不像指数衰减那么快但最终适应度值要低15%以上代价函数里的障碍惩罚项可以稳定清零。3. 无人机路径规划问题建模从连续三维空间到适应度函数3.1 环境建模与航路点编码方式路径规划的第一步是把物理世界翻译成优化问题能理解的数学形式。项目里地图尺寸固定为100×100×50x轴和y轴对应水平面z轴对应飞行高度。起点坐标设为[10, 10, 10]终点坐标设为[90, 90, 40]这保证无人机要穿越地图核心区域路径有足够的优化空间。中间飞行轨迹用n个航路点表示每个航路点有x、y、z三个坐标所以问题维度是3n。代码里取n6维度就是18维这个规模对CPO来说非常合适再增大到n10也不至于让算法崩溃只是收敛速度会变慢。编码方式就直接用连续浮点数向量不需要像GA那样做二进制编码省了不少功夫。障碍物在仿真环境里用圆柱体表示每个圆柱用中心坐标[x, y]、半径r和高度范围表示。选择圆柱体是因为它在水平和垂直两个方向的约束解耦代码里判断安全距离很简单先看航路点是否在圆柱高度范围内再看水平投影距离是否小于半径加安全余量。这个模型够用而且方便后续替换成不规则凸多面体。3.2 目标函数设计四个代价项的结构无人机路径规划的目标函数不是单纯的最短路径要把飞行品质和安全约束都揉进去。项目里我采用的适应度函数是四项加权和F w1 * 路径总长度 w2 * 平滑代价 w3 * 障碍代价 w4 * 高度代价路径长度比较好理解就是把起点、所有航路点、终点依次连起来算欧氏距离之和。平滑代价用来约束无人机转弯的剧烈程度做法是统计每连续三个点形成的夹角如果夹角小于某个阈值说明这个弯拐得太急就要累计额外惩罚。障碍代价是这样计算的对每一个航路点计算它到每个障碍圆柱的水平投影距离如果小于安全距离阈值按超出程度的平方累加惩罚平方惩罚比线性惩罚更合理它会让算法主动远离障碍而不是贴着安全边界飞。高度代价则是限制飞行高度必须在指定区间内太低容易撞地太高浪费能量。四个权重系数的选取直接影响优化结果的偏向。我在项目里的初始值是长度权重3、平滑权重1、障碍权重10、高度权重10障碍和高度权重高是因为安全永远是第一位的宁可路径绕一点也不能给出穿越障碍或贴近地面飞行的结果。3.3 约束转惩罚为什么不用强硬约束路径规划里的约束条件包括避障、高度限制、转弯角限制如果把这些约束直接作为硬性限制加入算法会让解空间变得支离破碎CPO的个体一旦落在不可行区域既无法更新也无法向其他个体提供有效信息搜索效率会急剧下降。所以项目里全部采用了惩罚函数法。惩罚函数法的本质是把约束违反程度变成代价的一部分让算法在优化过程中自动规避不可行区域而不是死板地判断和拒绝。这个做法在工程里很常见但要注意两点第一惩罚系数不能太大否则适应度值全是惩罚算法的梯度信息几乎为0第二惩罚系数也不能太小否则算法会认为轻微越过障碍是可以接受的。通过多次试验障碍惩罚系数设在10左右刚好能让障碍代价在总代价中占据主导但又不湮没路径长度信息。4. Matlab实现CPO路径规划的关键代码与运行流程4.1 文件结构与初始化设置Matlab整个项目不复杂四个核心文件就够了main_cpo_pathplanning.m 主程序负责参数设置和流程控制 fitness_function.m 适应度函数返回单条路径的代价 cpo_optimizer.m 穿山甲优化算法主循环 plot_results.m 路径三维可视化与收敛曲线绘制初始化部分做主地图、障碍物、算法参数三类事情。地图和障碍物参数固定写在主程序头部方便修改。算法参数包括种群数量、最大迭代次数、探索概率初值、扰动衰减系数、维度、上下界等。特别注意变量上下界航路点的x、y限定在[5, 95]z限定在[8, 45]起点和终点附近还要留出可飞行高度避免算法在最开始就不断命中边界。初始化种群的Matlab代码标准写法是pop lb rand(popNum, dim) .* (ub - lb);这种写法保证每个个体维度上的值在上下界内均匀分布。首个体可以直接设为一条直线均匀插值路径这样即使后面搜索完全失败至少还有一个合理的保底解可以输出。4.2 适应度函数的Matlab实现细节适应度函数是路径规划的灵魂必须隔离成独立文件反复调试这里直接用比较清晰的循环写法展示。先构造从起点经航路点到终点的完整坐标序列然后依次计算长度、平滑度、障碍和高度代价。function cost fitness_function(x, map) % x是待优化的航路点坐标向量map是地图信息结构体 n map.n; % 中间航路点数量 points [map.start; reshape(x, 3, n); map.goal]; ptsNum size(points, 1); % 路径长度 segLen zeros(ptsNum - 1, 1); for i 1:ptsNum - 1 segLen(i) norm(points(i 1, :) - points(i, :)); end pathLength sum(segLen); % 平滑代价三点夹角惩罚 smoothCost 0; for i 2:ptsNum - 1 v1 points(i, :) - points(i - 1, :); v2 points(i 1, :) - points(i, :); cosAngle sum(v1 .* v2) / (norm(v1) * norm(v2) 1e-10); angle acos(max(-1, min(1, cosAngle))); if angle map.minAngle smoothCost smoothCost (map.minAngle - angle)^2; end end % 障碍代价 obstacleCost 0; for k 2:ptsNum - 1 for j 1:length(map.obstacles) obs map.obstacles(j); if points(k, 3) obs.zMin points(k, 3) obs.zMax d norm(points(k, 1:2) - obs.xy); over obs.r map.clearance - d; if over 0 obstacleCost obstacleCost over^2; end end end end % 高度代价 heightCost 0; for k 2:ptsNum - 1 if points(k, 3) map.zMin heightCost heightCost (map.zMin - points(k, 3))^2; elseif points(k, 3) map.zMax heightCost heightCost (points(k, 3) - map.zMax)^2; end end cost map.w1 * pathLength map.w2 * smoothCost ... map.w3 * obstacleCost map.w4 * heightCost; end这个函数里有个容易踩的坑计算夹角时v1或v2长度可能为0导致除以0问题。虽然路径重复点基本不会出现但为了避免偶尔的退化个体导致NaN值污染整个种群代码里在分母上加了一个1e-10的微小常数。另外acos内部必须做clamp处理否则浮点数误差会让cosAngle略微超出[-1,1]范围acos返回NaN。没有这一层保护整个寻优过程会莫名其妙地失败而且从适应度数值上非常难定位问题。4.3 CPO主循环代码骨架穿山甲算法的迭代核心在cpo_optimizer.m中结构足够通用。每次迭代把探索概率按线性规律衰减每个个体根据随机数和概率分两路更新。探索分支中用全局最优加一个历史信息素影响量开发分支中在个体当前解附近按衰减半径做区域扰动。function [bestSol, bestCost, costHistory] cpo_optimizer(map, opt) popNum opt.popNum; dim opt.dim; maxIter opt.maxIter; lb opt.lb; ub opt.ub; pop lb rand(popNum, dim) .* (ub - lb); costs zeros(popNum, 1); for i 1:popNum costs(i) fitness_function(pop(i, :), map); end [bestCost, bestIdx] min(costs); bestSol pop(bestIdx, :); costHistory zeros(maxIter, 1); pInit 0.9; pEnd 0.1; for iter 1:maxIter p pInit - (pInit - pEnd) * (iter - 1) / (maxIter - 1); sigma 0.5 * (1 - (iter - 1) / maxIter); % 扰动半径衰减 for i 1:popNum if rand p % 探索朝向全局最优历史信息素 r rand * sigma; newSol bestSol r * (pop(i, :) - bestSol) ... (1 - r) * (ub lb) / 2; else % 开发围绕当前位置滚动扰动 newSol pop(i, :) sigma * randn(1, dim) .* (ub - lb); end % 边界处理 newSol max(min(newSol, ub), lb); newCost fitness_function(newSol, map); if newCost costs(i) pop(i, :) newSol; costs(i) newCost; else % 一定概率接受差解保留跳出能力 if rand 0.05 pop(i, :) newSol; costs(i) newCost; end end end [curBest, curIdx] min(costs); if curBest bestCost bestCost curBest; bestSol pop(curIdx, :); end costHistory(iter) bestCost; end end开发阶段的扰动使用randn服从标准正态分布乘上sigma和变量范围是为了保证扰动步长与解的尺度匹配。sigma从一开始的0.5线性降到0前期允许大步长在全局范围内改变路径结构后期扰动缩到一个很小的范围相当于在做局部的精细打磨。边界处理这里直接用clamp而不是反射或随机重置是因为clamp最简单且最稳定。反射处理在维度较高时容易把解挤在某个边界邻域里反而丧失多样性。末端加一个5%的随机接受差解概率用于防止算法在小规模种群下过早锁定在某个局部最优。整个流程跑完返回最优解、最优代价以及迭代收敛历史主程序里用costHistory画收敛曲线。4.4 结果可视化与路径输出Matlab画路径和障碍物三维图是项目交付时的关键一环好的图既能验证算法正确性也是给项目方讲结果时最有说服力的材料。可视化部分包括四个层面三维地图空间和障碍圆柱、最优路径线、航路点标记、迭代收敛曲线。figure; hold on; grid on; box on; % 绘制障碍物圆柱每个圆柱用多面体近似 for j 1:length(map.obstacles) obs map.obstacles(j); [cx, cy, cz] cylinder(obs.r, 60); cx cx obs.xy(1); cy cy obs.xy(2); cz cz * (obs.zMax - obs.zMin) obs.zMin; surf(cx, cy, cz, FaceColor, [0.5 0.5 0.5], EdgeColor, none, ... FaceAlpha, 0.3); end % 将最优解向量整理成航路点矩阵 n map.n; pts reshape(bestSol, 3, n); path [map.start; pts; map.goal]; plot3(path(:,1), path(:,2), path(:,3), r-o, LineWidth, 2, ... MarkerSize, 6); plot3(map.start(1), map.start(2), map.start(3), g^, MarkerSize, 10); plot3(map.goal(1), map.goal(2), map.goal(3), bp, MarkerSize, 10); view(45, 30); xlabel(x / m); ylabel(y / m); zlabel(z / m); axis equal; title(CPO路径规划结果);收敛曲线单独用一个图表示横坐标是迭代次数纵坐标是历史最优代价能直观看到算法在哪个阶段找到了主要绕行结构、在哪个阶段进行局部平滑。我习惯把收敛曲线和路径图放在同一个figure的两个subplot里提交报告时一张图就能说明全部结果。5. 仿真实验与参数调优5.1 三个测试场景与结果对比为了让实验结果更有说服力项目里设置了三个测试场景分别对应低、中、高复杂度。场景一只有两个稀疏障碍场景二在路径中心区域分布四个障碍物场景三在路径中心密集布置六个障碍形成一条需要S形穿行的航路。种群数统一为30迭代次数统一为200每组实验重复10次取最优值避免单次随机性干扰结论。最终结果整理成下面的表场景障碍数最优路径长度障碍代价平滑代价收敛迭代数简单场景2132.600.0857中等场景4145.900.2198复杂场景6168.300.32146可以看到障碍数越多路径自然越长因为没有约束时直线长度约为128.7复杂场景最终绕行长度增加约40个单位这是合理的结果。三个场景的障碍代价最终都收敛到0说明算法确实找到了安全路径不存在贴着障碍飞行的情况。平滑代价随复杂度上升是因为绕行需求迫使路径出现更多转弯这在物理上无法消除只能通过调整权重来均衡。5.2 参数敏感性分析种群数与迭代次数的权衡CPO的参数不多但种群数和最大迭代次数仍然需要仔细权衡。我做了一组实验以中等场景为基准比较(20,100)、(30,200)、(50,400)三组配置的表现。配置最优代价运行时间稳定性描述20个个体100次迭代171.2约2秒多次运行结果随机性大30个个体200次迭代146.4约6秒结果稳定随机性小50个个体400次迭代143.8约20秒收益递增不明显从工程角度讲(30,200)是性价比最高的组合。增加到(50,400)后代价只降低了不到2%但时间成本翻了四倍这在需要批量跑场景时完全没有必要。如果你只需要单次静态路径可以开到(50,400)求一个更优解如果是做算法对比实验、需要反复调参建议固定(30,200)。5.3 权重系数调优经验谈目标函数的四个权重是整个人工调参过程里最费时间的部分。我只分享两个最深刻的经验。第一个经验权重不要先按理论推导定先用一次快速运行看各项代价的相对数量级。比如时长项权重3但路径长度130左右贡献大约是390障碍权重10但障碍代价清零后贡献是0如果初始权重设得过大50和5000那么路径长度的优化信息会被安全约束的信息完全掩盖算法会为了保安全而牺牲过多的绕行距离。正确做法是先固定长度和平滑的权重用一轮实验观察障碍代价的均值再反向设障碍权重让障碍代价在总代价里的比例约30%到50%。第二个经验平滑代价权重不能设得太大。有人为了让路径好看把平滑权重调到5以上结果路径确实非常顺滑但在复杂场景下它会把原本合理的绕行路线磁化成一条掠障碍远距离的大弧线飞行路径长度严重超标。平滑是锦上添花长度才是核心效率指标两者权重比例建议保持在1比3左右。6. 常见问题与排查技巧实录6.1 适应度突然变成NaN或Inf的排查套路项目调试过程中最先遇到的坑是适应度出现NaN而且往往不是一开始就出现是跑了几十代后某次更新突然冒出来然后全场最优解被污染。排查步骤我整理成了固定套路第一步关掉随机性设固定随机种子复现问题第二步给适应度函数每个计算环节打印中间值看是哪一项先变成NaN第三步重点检查acos的参数范围、向量模长的除零点和norm函数中坐标差是否溢出。在路径规划这个特定场景里最容易出问题的是两点重合或三个连续点共线导致角度计算分母为0。解决办法是中间点编码时强制加入最小间距约束比如航路点之间坐标差不得小于0.5米或者在适应度函数里将重合点判为无效解并赋超大代价。前者的做法从源头杜绝异常后者也能工作但会让种群中大量个体进入低适应度区域搜索效率下降不推荐。6.2 路径卡在局部最优、绕障不走最优开口的解决记录有一轮实验比较典型中等场景下算法总是从左侧绕开障碍群明明右侧绕行路径短得多但前200代里从来没有个体尝试过右侧入口。原因在于初始种群全是在整个解空间均匀随机生成的生成的路径点之间没有连贯性每个点单独看是分散在地图各处连起来形成的初始路径往往穿过了不下三个障碍适应度值本身已经非常大导致CPO的探索分支即使想跳往右侧入口也被整体路径的高罚分拽了回来。这个问题的解法有三个层次项目里是按从低到高的顺序逐层尝试的。最低层次是增大种群数靠更大的样本覆盖右侧入口的路径结构但效果有限。其次是在初始化时加入一条直线插值路径作为第一个个体并且让部分个体在这条直线解附近做小幅扰动生成这样可以确保种群初期的解结构有一点连贯性。最高层次是在探索阶段加入方向扰动当最优解连续30次迭代没有更新时把探索步长临时增大一倍激活动量项沿横向偏移方向试错。最终采用第二个层次为主、第三个层次为辅的组合路径结果显著改善。6.3 结算速度太慢的向量化改造初版适应度函数里嵌套了三层循环六点路径加六个障碍物的情况下单次评估耗时大约0.4毫秒总觉得不太对劲。路径规划的问题规模其实很小单次评估耗时应该控制在0.1毫秒以内才合理。瓶颈在障碍代价部分隐藏循环导致每评估一个新解都要重新计算所有路径点和障碍物的距离。改造思路是把所有路径点和所有障碍物中心一次性构造成矩阵用Matlab的向量化运算批量计算距离矩阵再按阈值比较。改造后的核心代码大约是这样ptsMat reshape(x, 3, n); obsXY vertcat(map.obstacles.xy); distMat pdist2(ptsMat, obsXY); % 障碍高度判断 zInRange ptsMat(:,3) zMinArr ptsMat(:,3) zMaxArr; overMat (rArr map.clearance - distMat) .* zInRange; overMat(overMat 0) 0; obstacleCost sum(overMat(:).^2);同样规模的评估时间从0.4毫秒降到0.05毫秒整个200次迭代的寻优过程从几秒压缩到不到1秒。这个优化不影响任何算法逻辑属于纯工程收益但实验要跑大量对比时非常值钱。6.4 常见问题速查表把项目里遇到的问题整理成一个速查表方便你对照排查现象可能原因解决方法适应度为NaN角度计算acos越界、向量模长为0clamp处理、加微小常数、强制最小点间距障碍代价始终不为0惩罚权重过小、初始种群没有有效绕行结构调大障碍权重、初始化加入直线插值个体路径大量贴近障碍边缘安全余量clearance设置过小将安全余量从1米加到3米100次迭代后代价停滞探索概率衰减过快、扰动半径过小延长高探索概率区间、增大sigma初值多次运行结果差异大种群过小、随机种子未固定种群数提升到30以上、设置随机种子高维路径计算时间过长适应度函数未向量化改用矩阵运算替代循环路径不平滑、转折太急平滑权重过小或最小角度阈值过大调大平滑权重、把minAngle设为45度7. 扩展应用与后续改进方向这个项目做到最后路径规划的基本盘已经稳定但我也认真想过它还能往哪些方向延伸。CPO算法本身足够轻量化所以往动态环境扩展是自然的一步。当前的障碍物是静态圆柱体实际飞行场景里会出现临时禁飞区、移动的障碍物只要在适应度函数里把额外的动态障碍代价加上去重新跑一轮优化就能得到新路径。实时性方面由于一次规划不到1秒完全可以在飞行前或飞行间隙定期重新规划。多无人机协同也是一个直接相关的扩展方向。多机路径规划的难点不完全在单条路径优化而在机间避碰。可以在适应度函数中加入多机之间的空间距离代价让CPO同时优化多架无人机的路径序列。代价是问题维度翻倍但CPO的收敛特性在这里反而变成优势因为它没有GA那样的交叉算子多子群并行演化时互相干扰小更适合多机同时优化的场景。另外一个可以考虑的方向是把CPO和局部平滑器结合。CPO给出的路径虽然满足约束但航路点之间的连线是折线真实无人机飞行时会用B样条曲线或Dubins曲线做平滑。这个平滑过程最好不塞进CPO的适应度函数里否则每次评估的计算量会大幅增加而是用后处理的方式在CPO收敛后对路径做B样条拟合。用Matlab自带的样条函数就能完成代码量很小而且对路径质量的提升非常直观。我个人在实际操作中的体会是CPO这类新算法刚接触时总觉得比成熟算法这不如那不行但项目落地时胜在结构简单、改造成本低。你不需要为每个新场景重写算法主体只需把精力放在适应度函数的精准建模上这就已经比很多复杂算法的项目推进速度快很多了。最后再分享一个小技巧所有实验结果一定要保留随机种子和版本信息路径规划这类随机优化算法的复现性很大程度上取决于初始随机数发生器的状态。实验代码里固定随机种子收紧结果分析时的置信区间这个习惯能让你在复盘和向项目方汇报时少掉很多为难。
阅读完成 · 觉得有帮助?