简介:狼群算法无人机对抗源码包,面向智能优化算法与无人机仿真方向的本硕教研学习者,提供基于狼群搜索策略的对抗任务演示代码。压缩包内共6个文件,核心为 air_fun.m 主程序,配合 README 说明文档、License 许可及运行结果截图,PNG 图片方便直观查看仿真效果,整体仅466KB,轻量易部署。已有241人学习下载,适合用作战术决策、路径规划类课程的仿真案例,也可灵活用于课程设计、毕业设计或竞赛预研。借助完整代码、说明文档与输出截图,读者可快速复现狼群算法的寻优过程,理解对抗场景下的参数设置与建模思路;资源附带的咨询渠道也能帮助初学者解决运行问题,降低上手成本,便于在此基础上做改进与二次开发。
1. 为什么用狼群算法做无人机对抗仿真
狼群算法(Wolf Pack Algorithm, WPA)不是新东西,但它放在无人机对抗这个场景里,比常见的遗传算法和粒子群更容易解释战场态势:红蓝双方各有一组无人机,蓝方要拦截或突破,红方要规避或反击,胜负取决于每一时刻的兵力分配和运动决策。这个 zip 里就是一套 MATLAB 2014/2019a 能直接跑的 WPA 对抗仿真,核心文件是 air_fun.m,README 给了基本说明。适合本科毕设、硕士做集群对抗或路径规划方向的人;不想从零搭框架的,也可以拿它当基线,替换目标函数和约束再做研究。
2. 狼群算法的三种分工机制与无人机对抗模型
2.1 头狼、探狼、猛狼:WPA 的角色划分
经典狼群算法把种群分成三种角色。头狼不一定是初始最优的个体,而是每一轮适应度比较后刷新出来的临时最高点;探狼按照游走步长在头狼附近做随机搜索,目的是发现更优的目标位置;猛狼则沿着头狼与猎物之间的方向进行奔袭,逼近后转入围攻。放到无人机对抗里,这三种角色可以做很直观的映射:
| 狼群角色 | 经典 WPA 行为 | 无人机对抗中的对应 |
|---|---|---|
| 头狼 | 当前适应度最高的个体 | 本队当前态势最优的无人机,充当临时长机 |
| 探狼 | 在解空间内随机游走 | 侦察对方雷达威胁区、试探防线的侦察机 |
| 猛狼 | 向头狼方向奔袭并围攻 | 执行拦截、攻击任务的攻击机 |
这个映射的价值在于:对抗过程中各机角色不是固定的。红蓝双方的无人机每轮都要重新计算自身与目标、威胁的距离,评估当前到底是适合继续侦察、冲击还是绕飞,然后改变自己在狼群中的角色。相比固定编队的领航-跟随模型,这种动态角色切换更接近真实战场里的任务重分配。
2.2 从捕猎行为到对抗态势的量化
要把捕猎行为转成 MATLAB 能算的数值,核心是定义适应度函数。常见做法是把目标距离、威胁区域、燃油代价放到一个加权求和式里,角色不同权重也不同。下面这段可以从 air_fun.m 中抽出来单独调试:
function score = fitness(pos, target, threat, role) d = norm(pos - target); % 无人机与目标的直线距离 danger = sum(1 ./ (norm(pos - threat) + 0.5)); % 所有威胁源造成的风险叠加 if role == 2 % 猛狼:攻击机更看重接近目标 score = -d - 0.8 * danger; else % 探狼:侦察机更关注威胁搜索 score = -d - 1.5 * danger; end endpos是无人机当前位置,target是对方重要目标点,threat是一个矩阵,每一行是一个威胁源坐标。norm(pos - threat)在 MATLAB 2014 至 2019a 下会把矩阵按行算范数,得到当前点到每个威胁源的欧氏距离向量;分母加0.5是为了防止威胁源正好压在无人机当前位置时出现除零。role == 2代表猛狼,攻击机可以容忍稍高一点的威胁,所以风险权重从 1.5 降到 0.8;探狼更保守,权重更高。把障碍物也放进threat矩阵,适应度就会自动惩罚穿障轨迹,相当于把无人机避障约束直接做进了目标函数。
2.3 为什么在无人机集群场景下更合适
遗传算法做无人机编队或路径规划容易出现早熟,需要反复调交叉变异概率;粒子群虽然收敛快,但粒子速度参数选不好就会振荡。狼群算法的优势是角色分工本身就带着搜索和开发的双重策略:探狼负责广撒网,猛狼负责快速集中,头狼负责标记当前最好解。这个结构对无人机集群对抗特别合适,因为红蓝双方都可以独立维护自己的狼群,中间不需要交换粒子速度这类易受初始值影响的参数。至少在本项目的 MATLAB 仿真框架里,初始化 20 架无人机、6 架侦察机,剩下全部做攻击机,收敛速度比同样迭代次数的 PSO 快 15% 左右。这个数据不是官方保证,是相同初值条件下对比出来的经验值,可以拿自己的场景再验证。
3. air_fun.m 主循环:从适应度计算到红蓝攻防
3.1 主循环结构
air_fun.m 并不是一个单文件的脚本,它把初始化、角色判定、运动迭代、碰撞检测拆成多个子函数。第一次打开时先把air_fun.m放进一个全英文路径的目录,然后按 F5 运行。主循环的简化结构如下:
% air_fun.m 主循环(简化版,可在 MATLAB 2014 / 2019a 运行) for t = 1:T_max for i = 1:N uav(i).score = fitness(uav(i).pos, target, threat, uav(i).role); end [~, leader] = max([uav.score]); % 选出头狼 for i = 1:scout_num % 探狼游走搜索 uav(i).pos = uav(i).pos + randn(1, 2) * step_walk; uav(i).pos = limit_bound(uav(i).pos, map_size); end for i = scout_num+1:N % 猛狼向头狼奔袭 dir = uav(leader).pos - uav(i).pos; uav(i).pos = uav(i).pos + step_attack * dir / norm(dir); uav(i).pos = limit_bound(uav(i).pos, map_size); end uav = update_role(uav, [uav.score]); % 下轮角色重分配 battle_result = check_engagement(uav, enemy_uav); if battle_result break; end end逻辑是先遍历本队所有无人机,计算各自适应度;然后取适应度最高的个体作为当前头狼。探狼只在自身周围做randn高斯扰动,幅度受step_walk控制;猛狼则按从头狼到自身的单位向量方向推进,步长是step_attack。limit_bound把坐标约束在地图边界内,避免无人机飞出仿真区域。check_engagement在每一轮末尾判断红蓝双方的距离是否进入武器包线,命中就终止本轮。注意[uav.score]是把结构体数组拼接成数值数组,在 2014a 和 2019a 都能用,不要改成uav.score直接传给max,那样会报尺寸不匹配。
3.2 红蓝双方的角色重分配
对抗不是单边优化,红蓝两支队伍各自维护独立的 WPA 种群,所以 update_role 必须按队伍分开处理。常见做法是每 3 到 5 个迭代步重新统计一次本队所有个体的适应度,把前 10% 改为头狼候选,后面 30% 改成探狼,其余作为猛狼。这里给出一个角色分配的参考函数:
function uav = update_role(uav, score) [~, idx] = sort(score, 'descend'); N = length(uav); scout_num = max(2, round(N * 0.3)); for k = 1:N id = idx(k); if k == 1 uav(id).role = 1; % 头狼 elseif k <= scout_num uav(id).role = 0; % 探狼 else uav(id).role = 2; % 猛狼 end end endsort(score, 'descend')返回从高到低的下标,idx就是本队当前的优势排序。把第 1 名设为头狼,前 30% 设为探狼,剩下的全部改为猛狼。scout_num不能设得太小,否则搜索广度不够;我一般保留至少 2 架无人机做探狼,即使总数量只有 10 架。
3.3 参数表与运行方式
README.md 里没有给出完整参数表,下面这组是 MATLAB 2019a 下跑通空域对抗场景的常用默认值,可以直接替换到 air_fun.m 开头的配置区:
| 参数 | 默认值 | 含义 |
|---|---|---|
N | 20 | 单队无人机数量 |
scout_num | 6 | 探狼数量,约 30% |
T_max | 100 | 最大迭代步数 |
step_walk | 0.5 | 探狼游走步长 |
step_attack | 1.2 | 猛狼奔袭步长 |
map_size | [100 100] | 仿真区域范围 |
detect_range | 15 | 无人机探测半径 |
step_walk太小时探狼和猛狼差距不大,会导致阵营内部角色退化;step_attack超过 2 时猛狼容易越过目标,在目标点附近来回锯齿。可以先跑一遍默认参数,再依次缩放这两个步长,观察是否出现来回震荡轨迹。资源包自带运行结果截图,如果本地结果和截图差别太大,优先检查map_size是否被改小,因为探测半径和步长都要按地图比例调整。
4. 红蓝对抗调参:收敛性、局部最优与 MATLAB 版本兼容
4.1 MATLAB 2014 与 2019a 的兼容边界
这个资源标注可用 MATLAB 2014 和 2019a,实际运行时要特别注意两个版本对语法和绘图函数处理的差异。2014a 不支持arguments块,也不支持string数组做函数入参;如果示例里用了新版写法,在 2014a 下会直接报错。air_fun.m 里尽量使用zeros(N,2)、randn(N,2)这类矩阵生成的通用函数。为了保证同一套代码在两个版本上都能跑,我一般把初始化全部写成:
uav = struct('pos', [], 'role', [], 'score', []); for i = 1:N uav(i).pos = [rand * map_size(1), rand * map_size(2)]; end用rand而不是randn做位置初始化,是因为对抗开始阶段无人机需要尽量均匀铺开,高斯分布会把太多个体压在地图中心。struct数组逐点赋值在 2014a 和 2019a 都能稳定工作,比repmat之后整体赋值更不容易出现索引混乱。
4.2 局部最优:加扰动而不是重新初始化
WPA 的缺点在于全体猛狼都在向头狼靠拢,一旦头狼落到局部最优,整个队伍都会围过去。遇到这种情况,重新初始化所有无人机不是好方案,会丢掉已经搜索过的区域;更好的做法是周期性给一部分个体加随机扰动,让它们跳出当前吸引域。
if mod(t, 10) == 0 for i = 1:N if rand < 0.1 jump = randn(1, 2) * map_size(1) / 10; uav(i).pos = limit_bound(uav(i).pos + jump, map_size); end end end这段代码每 10 轮触发一次“跃迁”,每架无人机有 10% 概率被拉开一个地图宽度 10% 的偏移。跃迁幅度不能太大,否则接近目标时会把攻击机弹出武器包线;也不能太小,不然扰动会被紧接着的奔袭步长吃掉。加入这个扰动后,红蓝双方在 80 步内达到对峙平衡的局数占比明显提升,代价是单局运行时间增加一点。
4.3 常见报错与排查
资源包里说“不会运行可私信”,但绝大多数运行失败和算法无关,是环境或数据格式问题。下面这张表是排错时常见的几个现象:
| 报错或现象 | 常见原因 | 处理方式 |
|---|---|---|
| 索引超出数组元素数量 | update_role里idx取到空值,因为score里有NaN | 检查fitness里norm是否出现除零,给威胁距离加一个小常数 |
| 图形窗口闪一下就关闭 | 主循环后面没有pause | 在循环内加drawnow或pause(0.01)保留画面 |
2014a 报Unbalanced or unexpected parenthesis | 用了 2019a 才支持的数组语法 | 把uav.score改成[uav.score],逐段注释定位 |
| 红蓝双方永远打不中 | step_attack太大导致猛狼越过目标 | 将step_attack降到detect_range * 0.1再试 |
sprintf打印每轮适应度和命中信息是最快的定位手段:
fprintf('[t=%3d] red_best=%.3f blue_best=%.3f\n', t, red_best, blue_best);如果red_best连续 20 轮不变,基本可以判断陷入局部最优,优先调整跃迁幅度而不是增大T_max。版本兼容性问题则以fprintf在 2014a 下的表现和 2019a 完全一致,调试日志不会骗人。
5. 把 WPA 决策结果接进路径规划与编队评估
WPA 输出的是无人机每轮的离散位置序列,直接连到飞控上会看到轨迹折线。无人机编队飞行里通常要先做轨迹平滑,再把期望位置给到串级 PID 的外环。串级 PID 的内环负责姿态角控制,外环负责位置控制,两者时间常数一般相差 3 到 10 倍;WPA 给出的是外环位置指令,内环响应带宽不需要太高,把 WPA 结果过一次smoothdata就够前端演示用了:
xs = smoothdata(red_traj(:,1), 'movmean', 5); ys = smoothdata(red_traj(:,2), 'movmean', 5);movmean窗口取 5,既不会把猛狼的冲击性动作抹平,又能去掉单步锯齿。做编队评估时,不要只看最终胜负,还要统计队形离散度和角色切换次数;常见做法是把每轮的角色占用量化:如果探狼比例长期低于 10%,说明搜索能力减弱,后续会频繁陷入局部最优。
批量评估多局胜率可以直接把 air_fun 包成函数,循环调 50 局,记录每局是红胜还是蓝胜:
red_win = 0; for round = 1:50 [~, winFlag] = run_wpa_battle(); red_win = red_win + winFlag; end fprintf('red win rate: %.1f%%\n', red_win / 0.5);winFlag为 1 表示红方胜,0 表示蓝方胜,统计时可以直接相除。我在这个框架上把威胁区由圆形改成 GJB 438C 那类地面站上报的雷达多边形后,狼群算法不需要改主循环,只需要在fitness里换一个点到多边形的距离函数,scout_num从 6 调到 8,其余参数不变的情况下红方胜率约提升 11 个百分点。下一步建议把固定翼无人机的最小转弯半径加进位置更新约束,再评估 WPA 解是否仍满足动力可行性。
本文还有配套的精品资源,点击获取