
1. 项目概述从一道赛题到一套实战方法论看到“2020年第十七届数模竞赛D题 无人机集群协同对抗 建模”这个标题很多参加过数学建模竞赛的朋友尤其是对军事运筹、多智能体系统感兴趣的同学估计会心一笑。这道题当年可以说是“出圈”了它把当时学术界和工业界都非常前沿的“无人机集群”和“协同对抗”概念直接搬到了本科生的竞赛舞台上。题目要求参赛队为红蓝双方无人机集群设计协同策略在对抗环境中完成区域侦察、目标打击等任务并建立数学模型进行仿真分析。这远不止是一道数学题它本质上是一个高度简化的多智能体强化学习MARL或博弈论在动态对抗环境下的综合应用问题。我当年作为指导老师带过几支队伍啃这块硬骨头赛后也复盘了很久。这道题的魅力在于它没有标准答案却有一个清晰的评价维度你的模型是否合理地抽象了现实你的策略是否具备智能涌现的潜力你的仿真是否可信且高效。今天我不打算仅仅复现某支队伍的解法而是想结合这几年多智能体领域的发展系统性地拆解这道题分享一套从问题分析、模型建立、算法选型到代码实现的完整实战思路。无论你是想重温经典赛题还是正在研究无人机集群、智能博弈这篇文章都能提供一个扎实的起点。2. 核心问题拆解与建模框架设计面对“协同对抗”这种复杂问题最忌讳的就是一上来就埋头写公式或敲代码。第一步必须是解构把大问题分解成一系列可建模、可计算的子问题。2.1 对抗场景与规则抽象原题通常会给出一个想定背景例如红蓝双方各有N架无人机在一个二维或三维的矩形战场内无人机有速度、航向、传感器探测范围、武器攻击范围、生命值或燃油量等属性任务可能包括占领关键区域、侦察敌方目标、攻击敌方单位等胜负判定可能基于任务完成度、战损比等。我们的首要任务是将这些自然语言描述转化为数学规则和状态空间。实体建模每架无人机是一个智能体Agent。其状态至少包括位置 $(x, y, z)$、速度矢量 $\vec{v}$、航向角 $\psi$、剩余生命值 $H$、剩余弹药 $A$、当前任务状态如巡航、侦察、攻击、规避。环境建模战场是一个有边界的连续或离散空间。需要定义地形、障碍物可选、关键区域目标点的位置和属性。交互规则建模探测模型通常简化为一个以无人机为中心的圆形或扇形区域。当敌方单位进入此区域即被“发现”。可以引入探测概率、误报率来增加真实性。通信模型集群内部如何共享信息是全连通每架无人机都知道所有队友的信息还是有限距离/带宽通信这直接决定了你采用集中式还是分布式控制架构。攻击模型当满足攻击条件敌人在射程内、弹药充足、满足攻击角度等时发起攻击。攻击结果可以用概率命中模型或确定性扣除生命值来模拟。运动模型最简单的可用质点模型通过控制速度矢量和航向角来更新位置。更复杂的可以考虑动力学约束如最大加速度、转弯半径等。注意在竞赛有限的时间内必须在“模型真实性”和“计算复杂性”之间取得平衡。建议采用“简单模型复杂策略”的思路。即用尽可能简单的几何和概率模型来描述物理交互如圆形探测、概率命中而把建模的重点和计算资源留给策略的智能性上。2.2 核心矛盾与决策层次分析无人机集群对抗的核心矛盾体现在两个层面个体与群体的矛盾单架无人机需要根据自身感知做出决策如追击眼前敌人但这个决策可能不利于整体如落入敌方包围圈。因此模型必须引入协同机制。对抗双方的博弈矛盾红方的策略会影响蓝方的最优策略反之亦然。这不是简单的优化问题而是动态博弈。基于此我们可以设计一个三层决策框架这在实践中非常有效任务分配层战略层根据全局态势已知的敌方信息、己方状态、任务目标将宏观任务分解并分配给具体的无人机或小队。例如“无人机1和2去侦察A区无人机3-5编队攻击敌方目标B”。这可以建模为一个动态分配问题使用拍卖算法Auction Algorithm、合同网协议Contract Net Protocol或基于效益的贪心算法来解决。协同策略层战术层接受任务的无人机编队需要协同完成子任务。例如攻击编队需要形成有利的攻击阵型如“V”形或“菱形”并协同选择攻击目标和时机。这常常涉及编队控制Formation Control和协同目标选择。个体控制层执行层单架无人机根据上层指令和局部环境生成具体的控制指令速度、航向、是否开火。这可以是一个路径规划问题如避开障碍、接近目标或反应式行为如发现被锁定后立即进行机动规避。在竞赛模型中未必需要显式地实现这三层但你的模型设计必须能体现出这种“分层决策”的思想让智能行为既有全局观又有局部灵活性。3. 模型构建与关键算法选型有了框架接下来就是为每一部分填充具体的数学模型和算法。这是整个项目的核心。3.1 态势评估与效益函数设计任何智能决策都基于对当前“好坏”的判断。我们需要为无人机或编队设计一个效益函数Utility Function或奖励函数Reward Function。这是驱动整个系统向目标前进的“指挥棒”。效益函数通常是多目标的加权和例如 $U_i w_1 \cdot \text{TaskProgress} w_2 \cdot \text{SurvivalAdvantage} - w_3 \cdot \text{EnergyCost} w_4 \cdot \text{CohesionScore}$任务进度与目标点的距离倒数、是否完成侦察/攻击动作。生存优势自身生命值、与最近敌人的距离距离越远越安全、是否处于友方掩护范围内。代价移动消耗的燃油、弹药消耗。协同度与友机保持期望队形的误差、信息共享的覆盖率。设计效益函数是一门艺术。权重 $(w_1, w_2, …)$ 的设定需要反复调试并且可以根据任务阶段动态调整。例如在进攻阶段更看重任务进度在劣势时更看重生存。3.2 协同任务分配模型假设我们有M个任务目标点和N架无人机。任务分配的目标是最大化整体效益。这是一个组合优化问题。1. 基于拍卖的分布式分配这是一种非常契合分布式集群思想的算法。每架无人机相当于一个“投标者”。步骤每个任务由一个“拍卖商”可以是某个无人机或虚拟中心发布包含任务描述和当前最高出价初始为0。每架无人机计算自己对每个任务的“效益值”即完成该任务能获得的收益减去成本。无人机对自己效益最高的任务出价出价效益值。拍卖商收集出价将任务授予出价最高者并将该出价更新为新的最高价。未中标的无人机重新计算效益因为有些任务已被分配局势变了对剩余任务继续出价。重复直到所有任务被分配或没有无人机再改变出价。优点分布式通信量小自适应性强。缺点可能收敛到局部最优。2. 匈牙利算法Hungarian Algorithm或KM算法如果问题可以规约为一个二分图最大权匹配问题即每架无人机只能执行一个任务每个任务只需要一架无人机那么匈牙利算法可以在多项式时间内求得全局最优解。效益矩阵就是权重矩阵。优点全局最优效率高。缺点要求“一对一”分配且通常是集中式计算。对于“多对一”多架无人机协同一个任务的情况需要改进。在实际编程中对于规模不大的集群N20使用匈牙利算法求取每一时刻的最优分配是可行的。代码库如scipy.optimize.linear_sum_assignment里有现成的高效实现。3.3 集群编队与协同控制模型分配好任务后执行同一任务的无人机需要组成编队。常见的编队控制方法有基于领导者-跟随者Leader-Follower指定一架无人机为长机其余僚机根据与长机的相对位置偏移量来运动。实现简单但长机被击毁则编队失效。基于虚拟结构Virtual Structure将整个编队视为一个刚性的虚拟结构每架无人机对应结构上的一个点。通过控制这个虚拟结构的运动来控制编队。协同性好但机动不灵活。基于行为Behavior-Based为每架无人机设计几种基本行为如“避碰”、“聚集”、“朝向目标”其最终控制指令是这些行为输出的加权和。这种方法鲁棒性强行为涌现自然但设计和调参复杂。在竞赛模型中基于虚拟结构与人工势场法结合是一个不错的折中方案。为编队定义一个期望的几何形状如三角形计算出每架无人机在形状中的期望相对位置。在无人机运动时除了受到目标点的吸引力还受到两个势场力的作用编队势场力吸引无人机向其期望相对位置移动。排斥势场力防止无人机与友机、障碍物发生碰撞。无人机的控制指令加速度由这些力的合力决定。这样编队既能保持整体形状又能灵活地规避障碍和应对突发情况。3.4 对抗策略与博弈论建模红蓝对抗是典型的零和博弈或非合作博弈。完全理性的双方会采取纳什均衡策略。但在动态、不完全信息的环境下求解纳什均衡极其困难。实用化的博弈策略Minimax 搜索在决策树较浅时可用。我方红方假设蓝方总是采取对我方最不利的行动我方则选择在此前提下对我方最有利的行动。这需要定义几步之内的收益函数。强化学习多智能体强化学习 MARL这是目前最前沿也最契合本题思路的方法。让红蓝双方无人机在仿真环境中不断试错通过奖励/惩罚来学习最优策略。常用的算法有MADDPG适用于连续动作空间采用集中式训练、分布式执行的框架非常适合本场景。QMIX适用于离散动作空间通过一个混合网络来协调个体Q值保证联合动作的全局最优性。在竞赛中的应用由于训练耗时通常无法从头训练。但可以用强化学习的思想来设计规则。例如将效益函数视为即时奖励让无人机采用一种简单的策略梯度方法在线调整其行为权重这相当于一个极简的在线自适应学习器。对于数模竞赛更可行的方案是设计基于规则的专家系统并融入简单的博弈思想。例如“田忌赛马”式策略用我方的高性能无人机去牵制对方的王牌用中低性能无人机集群去快速完成核心任务。诱饵与伏击派少量无人机作为诱饵吸引敌方主力进入我方预设的伏击区域。动态角色切换根据战场态势无人机可以在“侦察机”、“攻击机”、“护航机”角色间切换其效益函数和行为规则也随之改变。4. 仿真实现与代码核心模块解析理论模型最终要靠仿真来验证。我们将使用Python进行仿真因为它有丰富的科学计算和可视化库。整个仿真系统可以划分为以下几个模块4.1 环境与实体类定义首先定义核心的数据结构。import numpy as np import matplotlib.pyplot as plt from enum import Enum class TaskType(Enum): RECON 1 ATTACK 2 DEFEND 3 class UAV: def __init__(self, id, team, pos, max_speed, sensor_range, weapon_range, health): self.id id self.team team # red or blue self.pos np.array(pos, dtypefloat) # [x, y] self.vel np.array([0.0, 0.0]) self.max_speed max_speed self.sensor_range sensor_range self.weapon_range weapon_range self.health health self.ammo 5 # 弹药量 self.task None # 当前分配的任务 self.target None # 当前攻击/跟踪目标 self.detected_enemies [] # 感知到的敌方列表 def update_position(self, dt): 根据当前速度更新位置并施加边界限制 self.pos self.vel * dt # 简单边界反弹 if self.pos[0] 0 or self.pos[0] WORLD_WIDTH: self.vel[0] * -0.5 if self.pos[1] 0 or self.pos[1] WORLD_HEIGHT: self.vel[1] * -0.5 self.pos np.clip(self.pos, [0,0], [WORLD_WIDTH, WORLD_HEIGHT]) def sense(self, all_uavs): 探测范围内的敌方单位 self.detected_enemies.clear() for uav in all_uavs: if uav.team ! self.team: dist np.linalg.norm(uav.pos - self.pos) if dist self.sensor_range: # 简单模型一定概率探测到 if np.random.rand() 0.2: # 80%探测概率 self.detected_enemies.append((uav.id, uav.pos.copy()))4.2 决策与控制系统这是大脑集成前面提到的效益计算、任务分配和运动控制。class DecisionSystem: def __init__(self, uav, all_tasks, team_uavs): self.uav uav self.all_tasks all_tasks self.team_uavs team_uavs # 所有友机信息用于协同 def calculate_utility(self, task): 计算本机对某个任务的效益值 base_score 100.0 distance_cost np.linalg.norm(task.position - self.uav.pos) # 效益与距离成反比与任务优先级成正比 utility base_score * task.priority / (distance_cost 1.0) # 如果弹药不足攻击任务的效益降低 if task.type TaskType.ATTACK and self.uav.ammo 1: utility * 0.3 return utility def auction_based_task_assignment(self, available_tasks): 简化的拍卖算法分配任务 best_task None best_utility -np.inf for task in available_tasks: u self.calculate_utility(task) if u best_utility: best_utility u best_task task return best_task def formation_control(self, assigned_task): 如果任务需要编队计算期望位置和编队控制力 if assigned_task.requires_formation: # 假设是简单的三角形编队本机是2号位 leader self.get_team_leader() # 获取长机 if leader is not None and leader.id ! self.uav.id: # 期望相对位置在长机右侧后方 desired_offset np.array([30.0, -20.0]) # 编队形状参数 desired_pos leader.pos desired_offset # 计算编队势场力吸引力 formation_force (desired_pos - self.uav.pos) * 0.05 return formation_force return np.array([0.0, 0.0]) def make_decision(self, dt): 综合决策生成控制指令加速度 # 1. 任务决策 available_tasks [t for t in self.all_tasks if t.is_active] if not self.uav.task or self.uav.task.is_completed: self.uav.task self.auction_based_task_assignment(available_tasks) total_force np.array([0.0, 0.0]) # 2. 目标点吸引力 if self.uav.task: dir_to_task self.uav.task.position - self.uav.pos dist np.linalg.norm(dir_to_task) if dist 1.0: task_force (dir_to_task / dist) * self.uav.max_speed * 0.1 total_force task_force # 3. 编队控制力 formation_force self.formation_control(self.uav.task) total_force formation_force # 4. 避碰排斥力与友机和障碍 repulsive_force self.calculate_repulsive_force() total_force repulsive_force # 5. 对抗行为如果有攻击目标增加追击力 if self.uav.target: dir_to_target self.uav.target.pos - self.uav.pos dist_to_target np.linalg.norm(dir_to_target) if dist_to_target self.uav.weapon_range * 1.5: # 进入交战范围 pursuit_force (dir_to_target / dist_to_target) * self.uav.max_speed * 0.15 total_force pursuit_force # 将合力转化为速度变化简单的动力学 acceleration total_force / 10.0 # 假设质量为10 self.uav.vel acceleration * dt # 速度限幅 speed np.linalg.norm(self.uav.vel) if speed self.uav.max_speed: self.uav.vel self.uav.vel / speed * self.uav.max_speed4.3 主仿真循环与可视化将各个模块串联起来并实现动态可视化。class BattlefieldSimulator: def __init__(self, red_uavs, blue_uavs, tasks): self.red_team red_uavs self.blue_team blue_uavs self.tasks tasks self.time 0.0 self.dt 0.1 # 仿真步长 def run_step(self): 运行一个仿真步 all_uavs self.red_team self.blue_team # 1. 更新所有无人机的感知 for uav in all_uavs: uav.sense(all_uavs) # 2. 红方决策与行动 for uav in self.red_team: # 为每架无人机创建决策系统实际中可以共享全局信息 ds DecisionSystem(uav, self.tasks, self.red_team) ds.make_decision(self.dt) uav.update_position(self.dt) self.check_combat(uav, self.blue_team) # 3. 蓝方决策与行动可以采用不同的策略 for uav in self.blue_team: # 蓝方可以使用更简单或不同的决策逻辑以体现策略差异 ds DecisionSystem(uav, self.tasks, self.blue_team) # 可以在这里修改蓝方的效益函数或行为参数实现不同策略 ds.make_decision(self.dt) uav.update_position(self.dt) self.check_combat(uav, self.red_team) # 4. 更新任务状态 for task in self.tasks: task.update(self.red_team, self.blue_team) self.time self.dt def check_combat(self, attacker, opponent_team): 简单的战斗判定 if attacker.ammo 0: return for opponent in opponent_team[:]: # 遍历副本 dist np.linalg.norm(opponent.pos - attacker.pos) if dist attacker.weapon_range: # 概率命中模型 hit_prob max(0.1, 1.0 - dist/attacker.weapon_range) # 距离越近命中率越高 if np.random.rand() hit_prob: opponent.health - 25 print(fTime {self.time:.1f}: {attacker.team} UAV-{attacker.id} hits {opponent.team} UAV-{opponent.id}. Health left: {opponent.health}) if opponent.health 0: print(f - {opponent.team} UAV-{opponent.id} destroyed!) opponent_team.remove(opponent) # 从列表中移除被摧毁单位 attacker.ammo - 1 break # 一次攻击一个目标 def visualize(self, ax): 可视化当前战场态势 ax.clear() ax.set_xlim(0, WORLD_WIDTH) ax.set_ylim(0, WORLD_HEIGHT) ax.set_title(fDrone Swarm Battle - Time: {self.time:.1f}s) # 绘制任务点 for task in self.tasks: color gold if task.is_active else gray ax.scatter(task.position[0], task.position[1], ccolor, s200, markers, alpha0.5) ax.text(task.position[0], task.position[1]10, task.name, hacenter) # 绘制红方无人机 for uav in self.red_team: ax.scatter(uav.pos[0], uav.pos[1], cred, s100, marker^) ax.text(uav.pos[0], uav.pos[1]-5, fR{uav.id}, hacenter, fontsize8) # 绘制探测范围 circle plt.Circle(uav.pos, uav.sensor_range, colorred, alpha0.1) ax.add_patch(circle) # 绘制蓝方无人机 for uav in self.blue_team: ax.scatter(uav.pos[0], uav.pos[1], cblue, s100, markero) ax.text(uav.pos[0], uav.pos[1]-5, fB{uav.id}, hacenter, fontsize8) circle plt.Circle(uav.pos, uav.sensor_range, colorblue, alpha0.1) ax.add_patch(circle) ax.grid(True, alpha0.3) ax.set_aspect(equal) # 主程序 if __name__ __main__: WORLD_WIDTH, WORLD_HEIGHT 400, 300 # 初始化任务 tasks [ Task(Recon Zone A, (100, 150), TaskType.RECON, priority1.0), Task(Attack Target B, (300, 200), TaskType.ATTACK, priority1.5), Task(Defend Base, (50, 50), TaskType.DEFEND, priority0.8), ] # 初始化红蓝双方无人机 red_team [UAV(i, red, (np.random.rand()*50, np.random.rand()*50100), 8.0, 60.0, 40.0, 100) for i in range(5)] blue_team [UAV(i, blue, (WORLD_WIDTH-np.random.rand()*50, np.random.rand()*50100), 7.5, 55.0, 35.0, 100) for i in range(5)] simulator BattlefieldSimulator(red_team, blue_team, tasks) # 动态可视化 fig, ax plt.subplots(figsize(10, 7)) plt.ion() # 开启交互模式 for step in range(300): # 仿真300步 simulator.run_step() if step % 5 0: # 每5步刷新一次画面 simulator.visualize(ax) plt.pause(0.05) # 判断终止条件 if len(red_team) 0 or len(blue_team) 0: print(fBattle ended at step {step}. Winner: {Red if len(red_team)0 else Blue}) break plt.ioff() plt.show()5. 模型评估、调优与策略分析建模仿真不是终点如何评价你的模型并从中提炼出有效的策略才是关键。5.1 设计评估指标体系不能只看“谁赢了”需要多维度量化评估评估维度具体指标计算方法/说明任务效能任务完成率(已完成任务数 / 总任务数) * 100%平均任务完成时间从开始到任务达标的平均时间作战效能战损比(摧毁敌机数 / 己方损失数)生存率(幸存己方单位 / 初始己方单位) * 100%协同效能编队保持度编队内无人机位置误差的平均值信息共享率成功接收/发送关键信息的比例效率决策耗时每仿真步所有无人机决策的平均时间总能耗/代价移动总距离、弹药消耗总量等在仿真中记录这些指标并绘制其随时间变化的曲线可以清晰对比不同策略的优劣。5.2 参数敏感性与策略调优你的模型中有大量参数效益函数的权重、势场力的系数、探测概率、命中概率、速度、射程等。这些参数微小的变化可能导致策略行为截然不同。系统性调优方法单变量分析固定其他参数只改变一个参数如攻击任务的权重 $w_{attack}$观察评估指标的变化。这能帮你理解每个参数的作用。网格搜索对2-3个最重要的参数进行组合遍历。虽然计算量大但对于参数空间不大的情况能找到较优解。启发式优化使用遗传算法GA、粒子群算法PSO来优化参数集。将你的仿真程序包装成一个“黑箱”函数输入是参数向量输出是综合得分如加权后的多项指标然后让优化算法去寻找最高分的参数。实操心得调参时不要追求在单一想定下的绝对最优。一个好的策略应该在多种初始条件如不同起始位置、不同任务组合下都表现稳健。因此你的评估应该基于多次蒙特卡洛仿真的平均结果。5.3 典型对抗策略的仿真对比分析基于上面的框架我们可以设计几组典型的红蓝策略进行对比实验实验1集中式 vs 分布式红方采用集中式匈牙利算法进行全局任务分配。蓝方采用分布式拍卖算法进行任务分配。分析集中式在信息完备时全局最优但通信负担重且中心节点脆弱分布式鲁棒性强但可能陷入局部最优。仿真可以展示在不同通信干扰下双方表现的差异。实验2激进进攻 vs 稳健防御红方效益函数中攻击任务权重极高倾向于快速接敌。蓝方效益函数中生存权重高倾向于保持距离、利用地形防御。分析通过战损比和任务完成率曲线可以分析哪种策略在特定场景下更有效。往往会出现“矛与盾”的博弈平衡点。实验3简单规则 vs 自适应规则红方使用固定参数的规则。蓝方引入简单的自适应机制例如当战损超过阈值时自动调高生存权重从进攻转为防守。分析自适应策略能否在长期对抗中占据优势这模拟了学习能力带来的优势。在仿真报告中用对比图表如并行的指标曲线图来呈现这些分析会非常有说服力。6. 从赛题到研究的延伸思考这道赛题做完其实只是打开了多智能体协同对抗世界的一扇门。如果你想继续深入以下几个方向值得探索引入不完全信息与通信约束现实中的无人机不可能拥有全局上帝视角。可以建模通信延迟、丢包、带宽限制让无人机仅基于局部不完全信息决策这会极大增加问题的挑战性也更贴近实际。从规则驱动到学习驱动用深度强化学习如MADDPG完全替代我们手写的决策系统。让智能体在仿真中从零开始学习协同策略甚至能涌现出人类未曾设计过的战术。异构集群建模现实中集群包含不同功能的无人机侦察型、攻击型、干扰型。如何为异构智能体设计任务分配和协同策略是一个更复杂也更有价值的问题。考虑更复杂的动力学模型将质点模型替换为更真实的六自由度或固定翼无人机模型引入气动约束这样生成的路径和控制指令才具有真正的可执行性。人在回路的协同将一到两架无人机设为人类操控研究智能无人机如何与有人机协同或者如何理解并配合人类的模糊指令。回过头看这道数模赛题的价值就在于它用一个足够具体又足够开放的问题逼着你去系统性地思考建模、算法、实现、评估的全流程。它锻炼的不仅仅是编程或数学能力更是将复杂现实问题抽象为可计算模型并通过计算实验去分析和解决问题的系统工程思维。这份思维框架无论是对于后续的学术研究还是从事智能系统、游戏AI、机器人等相关行业的工作都是极为宝贵的财富。