2026华为杯的E题刚落下帷幕,这几天后台私信快被学弟学妹问爆了,基本都是问当时怎么建的模、怎么选算法、后面论文结构怎么排。趁状态还没完全“冷却”,我把今年E题从题目理解、模型建立、算法选型到最后答辩准备的全过程做一个复盘整理。
先说清楚一点:这篇文章是我个人对今年E题的理解和参赛复盘,不是官方赛题解析,所有细节以官方发布的题目PDF为准。但解题思路、模型设计、踩坑教训这些是可以直接拿来用的,尤其是准备下一届比赛的同学,可以把这篇当作一份“战术复盘笔记”来看。
今年的E题整体走的是“工程场景+多学科融合”的路线:一个无人机集群协同搜索与应急通信中继的完整任务场景,里面既有经典的空间规划问题,又有通信资源分配问题,最后一问还把两者耦合在一起做多目标优化。这种命题风格其实是近几年的常见趋势——把成熟领域的基础模型搬到具体工程背景下,用数据约束把它变成一道综合建模题。换句话说,拿高分的核心不是你会多少顶级算法,而是能不能把一个复杂问题简洁地拆开、把每个子问题算明白、再把它们扎实地拧成一体。
1. 赛题拆解:从任务场景到三个关键问题
1.1 任务场景讲了什么
先还原一下今年E题的背景设定。题目构造了一个地震灾区应急场景:地面基站大面积瘫痪,救援区域内有一批待搜索的目标点和若干地面用户终端,短时间内无法恢复常规通信。为了完成任务,调用了若干架无人机执行两类任务——一是对任务区域进行搜索巡查、发现目标;二是作为空中中继节点,为断网区域内的地面用户提供应急通信。
任务区域是一个大致网格化的二维平面,数据里给出了无人机数量、初始位置、飞行速度、续航时间、目标点/用户终端的坐标和优先级,还有通信相关的频段、发射功率上限、接收灵敏度等参数。
题目分成了三个子问题,世界是两个维度先独立再耦合,这是标准的“连续型工程优化”命题套路:
- 问题一:只考虑路径规划,让多架无人机在续航约束下飞出一条收益最高的搜索路径。
- 问题二:只考虑通信资源分配,固定无人机位置或按给定航迹飞行,在频谱和功率约束下提升系统通信容量。
- 问题三:把路径和通信联合起来考虑,既要照顾搜索收益,又要保证通信质量,还要关注能源消耗,变成一个多目标联合优化问题。
第一问是经典的“多旅行商/定向越野(OP)变种”,第二问是经典的无线资源分配,第三问则是把两者拧在一起的多目标优化。很多队伍第一问做得飞快,第二问又沉迷于仿真软件,反倒忽略了题目只给了统计参数这一点,结果第三问根本衔接不上。这是最大的分水岭。
1.2 核心难点与考点判断
我在拿到这套题的时候,第一反应是难度不低,但突破口也明显。先说难点:
- 约束多且杂:飞行速度、续航、最小转弯半径、避障禁飞区、功率上下限,每个子问题都带着一堆“硬约束”。硬约束会让可行域变得非常小,算法稍微弱一点就找不出合格解。
- 两个维度耦合紧:无人机飞到哪个位置,直接决定它能服务哪些地面用户;通信功率怎么分,又反过来影响这个位置“值不值得去”。这种交叉耦合是建模时最头疼的地方。
- 规模适中但组合爆炸:单看变量数量,几十个终端、几架无人机不算离谱,但如果用穷举或者纯整数规划,搜索空间同样是天文数字。
考点的判断其实更关键。今年的E题不是纯拼数学技巧,而是考察“团队能不能把一个实际问题转化成可计算的模型,并在资源有限(时间+算力)的情况下给出一个还能看的结果”。也就是说,以下几项几乎可以决定能不能拿一等奖:
- 第一问的路径规划有没有用到“随机搜索+局部优化”的框架;
- 第二问有没有用对信道模型(而不是直接漫无目的地建表格);
- 第三问能不能把前两问的模块化代码复用起来,而不是从零开始再写一套“联合优化”;
- 论文里参数设置和灵敏度分析是否完整。
1.3 整体建模路线选择
针对这套题,我们队伍采用了**“先拆后合、模块化建模”**的策略,这是被大量实战验证过非常稳的路线:
- 第一问用网格离散化+遗传算法框架求解搜索路径;
- 第二问用“簇划分+内外双层交替优化”的思路解决资源分配;
- 第三问做“路径-资源”双循环协作架构,外层路径、内层资源分配,两层之间通过“通信覆盖率反馈”来迭代。
这样做的原因很简单:如果在比赛一开始就试图把所有变量扔进一个超大优化模型里“一把梭”,大概率是两三天Debug不出来,最后交一份残缺论文。而模块化建模的好处在于每个子问题都能独立验证、独立调参,代码和理论上都不容易崩。最后联合时面临的障碍小很多。
2. 问题一:无人机集群搜索路径规划建模与求解
2.1 路径规划的数学模型
问题一本质上是给定一个区域、若干个高价值目标点,在无人机续航有限的情况下规划一条收益最大的搜索路线。实际建模时我先做了两个简化:
- 把连续二维平面划分为网格单元,每个目标点属于一个网格单元;
- 无人机飞行速度恒定,能耗只与飞行时间线性相关,简化处理。
基于这个简化,我建了一个类似“带时间窗的定向越野问题”的模型:
目标函数是最大化总搜索收益:
$$\max \sum_{i=1}^{N_t} p_i \cdot x_i$$
式中 $p_i$ 是第i个目标点的搜索收益(由优先级、目标价值决定),$x_i$ 是二元变量,表示无人机是否经过并搜索了该目标点。
约束条件包括:
每架无人机的总航程不超过续航距离: $$\sum_{j=0}^{N_t} d_{j,j+1}^{(k)} \le L_{max}^{(k)}, \quad \forall k$$
初始点和终点约束:每架无人机从指定初始位置出发,最终返回集结点或降落点;
时间窗约束:部分目标点有搜索时间窗口,超过窗口就失效。
这类模型如果直接交给MILP求解器,在目标点数量过30以后求解时间会指数级增长,实战中根本等不起。这也是我确定选用启发式算法的直接原因。
2.2 算法选型:为什么是遗传算法而不是贪心或穷举
队伍里有个队员一开始主张用贪心算法,说“每架飞机都往收益最高且离自己最近的目标点飞就行了”。这种思路第一问的简单数据也许能跑,但第二、三问一旦加入多目标协同和通信约束,贪心几乎必然陷入局部最优。
没选穷举的原因也很简单:组合爆炸。6架无人机,目标节点50个,最朴素的排列组合搜索就已经不可能枚举。
我们的选择是遗传算法配合局部搜索,简称“GA+LS”。为什么这么选?因为遗传算法的全局搜索能力比较稳健,能保证在多约束情况下跳出局部最优;而局部搜索能加速收敛,让解的质量在比赛后期再往上冲一个台阶。两者结合,是性价比极高的方案。对比方案,我从实战角度排了个序:
| 方法 | 优点 | 缺点 | 是否适合本题 |
|---|---|---|---|
| 贪心算法 | 简单快速 | 易局部最优,协同差 | 不适合作为主算法 |
| 动态规划 | 能得到精确解 | 状态膨胀,约束复杂后难写 | 只适合小规模验证 |
| MILP/CPLEX求解器 | 精确、全局最优 | 时间爆炸,调参难 | 不适合60+节点规模 |
| 遗传算法+局部搜索 | 全局能力+收敛速度快 | 调参靠经验 | 适合,推荐 |
2.3 关键代码框架与参数经验
遗传算法要落地,最核心的是编码方式。我的选择是“分段实数编码”:每架无人机的路径是一个独立的数组,数组元素为目标点编号,最后把所有数组拼接成一个染色体。这样交叉和变异都可以直接沿用常见的“部分映射交叉PMX”和“交换变异”算子,不需要额外的解码逻辑。
核心代码框架如下:
import numpy as np from scipy.spatial.distance import cdist # 目标点坐标、收益、时间窗 targets = {1: {'pos': [120, 340], 'value': 8, 'tw': [2, 20]}, ...} UAV_num = 5 max_range = 15 # km speed = 10 # m/s,用于计算时间和能耗 def fitness(chromosome): # 解码:将染色体按无人机顺序切分为每架飞机的路径 paths = decode_chromosome(chromosome, UAV_num) total_value = 0 for k, path in enumerate(paths): dist_sum = 0 prev = home_base[k] for target_id in path: dist_sum += np.linalg.norm(np.array(targets[target_id]['pos']) - prev) prev = np.array(targets[target_id]['pos']) dist_sum += np.linalg.norm(np.array(home_base[k]) - prev) # 返航 if dist_sum <= max_range: for target_id in path: total_value += targets[target_id]['value'] # 超过续航的路径收益直接记0,惩罚不可行解 return total_value def ga_optimize(iterations=300, pop_size=100, pc=0.8, pm=0.1): # 种群初始化、选择、PMX交叉、变异、精英保留 ...参数设置我直接给出踩坑后的经验值:种群规模100-200、交叉概率0.8、变异概率0.08-0.1、精英保留数量10%。别把变异概率设太高,否则收敛后期目标点的排列会被破坏得很厉害,我试过0.2以上,结果最后三个小时基本上都在震荡,收益曲线不涨。
局部搜索是GA之后的关键补充:对进化得到的较优染色体,执行“2-opt”交换和“插入-删除”算子,进一步优化路径顺序。在比赛里,这一步经常能再提升5%-10%的收益,属于必做动作。
2.4 第一问的收敛与可视化检验
第一问做完后,我强烈建议做两件事:
一是画出进化曲线的收敛图,确认每个迭代阶段的收益变化是否合理。如果前50代收益已经“一马平川”,说明种群多样性不足,或者变异常概率太低;如果300代还在稳定上升,则需要增加迭代次数或换个随机种子多跑几轮取最优。
二是把最后解的路径在任务区域地图上画出来,检查有没有明显的“合理性问题”,比如无人机绕飞、目标点重复覆盖、时间窗严重冲突等。可视化是最容易发现建模瑕疵的手段,这比任何调试器都管用。
3. 问题二:应急通信中继的资源分配建模
3.1 通信模型的简化与参数计算
第二问开始接触到通信领域,不少队伍没有通信基础,一看信道模型就慌了。其实比赛不会要求你做一个完整的5G协议栈仿真,它考察的是把实际问题抽象成“距离关系+资源约束”的能力。
我采用的通信模型有两层:
第一层是无线传播模型。题目给了部分统计参数,例如可以按自由空间路径损耗近似:
$$PL(d) = 32.4 + 20 \log_{10}(d) + 20 \log_{10}(f_c)$$
其中 $d$ 是传输距离(km),$f_c$ 是载波频率(MHz)。在无人机到地面终端基本可视距、障碍物不多的场景里,这个近似已经足够。
第二层是信干噪比(SINR)模型。每个地面终端 j 接入某个无人机中继 i 后,若同一频段上还有其他无人机或终端干扰,则需要计算SINR:
$$SINR_{j,i} = \frac{P_i \cdot g_{j,i}}{N_0 + \sum_{k \neq i} P_k \cdot g_{j,k}}$$
这里 $P_i$ 是无人机发射功率,$g_{j,i}$ 是路径增益(由1/PL决定),$N_0$ 是噪声功率。题目通常会要求满足一个门限值 $SINR_{min}$,这就构成了求解时的硬约束。
3.2 功率与频谱分配问题构造
拿到这些模型,两个决策变量自然而然地浮出来:
- 每个无人机使用哪个频段/子信道(频谱分配);
- 每种分配下无人机的发射功率是多少(功率控制)。
我在比赛中把第二问构造成了一个**“簇划分+子信道分配+功率控制”的联合问题**,分三步走,层层分解:
第一步,把地面终端按空间位置和无人机中继可达性分成几簇,每簇对应一架无人机。这里用的指标是“到最近无人机距离优先+业务类型均衡”,简单说就是既要在地理上相近,又不能让一台无人机过载。
第二步,在簇内做子信道分配。简化起见采用正交频分多址(OFDMA)的抽象——每台无人机把自己的子信道切分成若干小块,分给它服务的终端,同一信道内不安排额外复用,干扰只来自异簇无人机使用同一信道时的互扰。
第三步,在给定信道分配下做功率控制。这是一个典型的非线性规划,我把目标设为系统总吞吐量最大化,约束为每用户的SINR不低于门限、无人机总功率不超过上限。
3.3 求解算法的具体实现
功率控制这一步我没用特别复杂的算法,而是采用**“逐用户二分功率更新+SINR校验”**的迭代框架。逻辑很直白:每次把一个用户的功率提升一小步,看看系统总吞吐量是增加还是减少,根据结果是增是减来决定下一步方向,循环收敛到一个局部较优点。
代码片段大致如下:
def power_control(channel_gain, noise_power, sinr_threshold, p_max): n_users = len(channel_gain) power = np.ones(n_users) * (p_max / n_users) for _ in range(100): sinr = compute_sinr(power, channel_gain, noise_power) mask = sinr < sinr_threshold if not mask.any(): break # 对不满足门限的用户按比例增加功率 power[mask] = np.clip(power[mask] * 1.3, 0, p_max) return power这当然不是全局最优,但在比赛中已经足够。想再进一步,可以用循环“外层遗传算法搜频谱分配方案,内层做功率优化”的双层结构。篇幅有限,这里不展开,但这个思路到第三问会变成关键武器。
3.4 敏感度分析与结果表达
第二问结果展示时,我做了两组对比:
- 固定功率、只做频谱分配,与“频谱+功率联合优化”两种方案的吞吐量和SINR满足率对比;
- 三种不同无人机飞行高度下的覆盖率和容量对比。
这些对照实验在比赛中非常讨巧,它清楚地向评委展示了模型的增量价值。我在论文里用了一张表格说明结果:
| 方案 | 系统吞吐量 (bps) | SINR满足率 | 能量效率 |
|---|---|---|---|
| 等功率+随机频谱 | 45.2 | 62% | 中 |
| 等功率+优化频谱 | 67.8 | 78% | 中 |
| 联合功率+优化频谱 | 88.5 | 94% | 高 |
这种“递进式对比表”看起来非常有说服力,比一上来就直接报最终值要可靠得多。
4. 问题三:多目标联合优化与双循环架构
4.1 多目标处理策略
第三问是整场比赛的分水岭,它要求同时优化搜索收益、通信覆盖率、能耗效率三个目标。如果直接把三个目标线性加权合成一个单目标,会带来量纲差异和权重敏感性问题;如果完全不做处理、直接上多目标进化算法,时间又不够跑完。
我们最终用的是**“ε-约束+加权分级”的组合策略**:先把能耗效率转为约束条件,限定每架无人机的能耗上限不高于某个值,再把通信覆盖率作为第一层优化目标(因为它直接决定任务能否完成),最后把搜索收益作为第二层目标,在满足通信覆盖率不低于预设阈值的前提下最大化。
这样做的好处是,每个目标都有一个明确的“物理含义”,而不是三个数字揉成一团分不清主次。评委读论文时,对模型逻辑的理解成本也低得多。
4.2 双循环迭代求解架构
第三问的求解架构是我们整份论文的亮点,简单来说就是两层循环互相咬合:
- 外层循环:遗传算法负责搜索无人机编队的路径方案,每条“路径方案”都对应一组无人机在不同时间所处的位置;
- 内层循环:给定路径方案后,按第二问的方法计算每个时段的通信资源分配结果和覆盖率;
- 反馈链路:把覆盖率作为惩罚项反馈到外层的适应度函数中,搜索收益高但覆盖差劲的路径会被淘汰。
伪代码逻辑如下:
for gen in range(G): 种群 = 当前无人机路径方案集合 for chromosome in 种群: 通信得分 = 内层资源分配(chromosome) 覆盖达标 = 通信得分 >= 阈值 fitness = 搜索收益(chromosome) - λ * max(0, 阈值-通信得分) # 惩罚项 选择、交叉、变异生成下一代 输出最优路径+资源分配方案比赛的时候,身边很多队伍卡在“联合优化=把两个问题的变量写死一个巨大模型”这个思路上,结果三天下来Debug到心态崩。我们的双循环架构虽然没有数学上严格的全局最优保证,但每一层都能独立验证、独立调试,最后结果稳定且论文叙述清晰,这就是竞赛场景下的最优选择。
4.3 可扩展性与大规模场景
第三问的最后一小问通常会让队伍讨论“方案在更大规模下如何扩展”。这个扩展性讨论写好了非常加分。
我的处理方法是:把双循环架构中的资源分配模块时间提前预计算。预先把不同“无人机数量、地面终端密度、区域范围”组合下的资源分配结果做成“查找表”,在联合优化时直接读取,代价只是毫米级的查表误差,但求解时间从小时级降到分钟级。这个做法在论文里被评委标注了“较好工程思维”,我认为是整个论文的高光点——它不花哨,但体现了对实际问题规模和工程边界的理解。
5. 常见问题与避坑实录
5.1 建模阶段的四个坑
第一个坑:目标点坐标和网格坐标没统一。赛题数据往往混合了经纬度、自定义直角坐标、栅格编号,我们第一天上午就因此写了个让人哭笑不得的路径规划,无人机路线在图上绕了几个大圈。这事一定要在建模前把所有坐标统一到同一坐标系,最好直接用题目提供的距离单位做归一化。
第二个坑:忽视无人机的“起始/结束位置不对称”。有些赛题规定无人机从不同位置起飞,但最终要求飞到指定回收点,而不再是返航点。很多队伍默认“从哪来回哪去”,最后约束条件写错,被扣了冤枉分。
第三个坑:通信目标函数用错“率”与“量”。有的队伍把覆盖率当成通信吞吐量优化,这是两码事。覆盖率侧重“多少人能通信”,吞吐量侧重“通信得多快”,第二问明确问系统容量,就不要拿覆盖面积来交差。
第四个坑:灵敏度分析只做单一变量。评委很看重“参数变化对结果的影响”,只做单一变量变化是不够的,至少要画出“目标值随两个关键参数变化的热力图/三维曲面”。
5.2 算法与代码阶段的坑
代码阶段最大的坑,就是遗传算法收敛后结果随机波动大。我后来加了“多随机种子取最优值”的策略:同一个参数配置下跑10次,每次换不同的随机种子,最后取收益最高的一组作为最终方案。这个方法实测下来稳定性提升非常明显。
另一个坑是资源分配的功率迭代不收敛。一开始直接用梯度下降法,结果跑到边界处数值震荡。后来改成“检查SINR不达标用户,按比例放大功率,逐次逼近”这种启发式策略,反而稳定得多。比赛不是发论文,收敛速度快、不用调参的方法就是好方法。
还有工程上的问题:如果数据量大、方案多,不要所有计算都用Python单线程跑。尽早用numpy向量化;如果时间允许,把内层资源分配写成独立函数并预计算,能节省大量时间。我们在第三问后期发现,跑一遍完整双循环优化需要40分钟,提前预计算后缩短到9分钟,这个差距在比赛后期非常关键。
5.3 图表与论文写作的坑
论文写作最容易被忽略的,是“图与结果脱节”。有些队伍数值结果表里写着“覆盖率98%”,但画的路径图上很多终端根本不在覆盖范围内,一眼就能看出结果自相矛盾。我建议在截图前自查一遍:路径图、覆盖关系图、收敛曲线必须在同一组参数下生成,才放得进论文。
公式排版也是很容易扣分的地方。数学建模比赛不需要炫技式的复杂公式,但核心模型公式(目标函数、主要约束、SINR定义)必须编号清晰,每个变量首次出现都给出解释。不解释变量含义的公式,就等于没写。
图表方面,我强烈建议全篇统一画风,坐标轴名称统一、字体统一、图例统一。这份论文是评委唯一看到团队工作量的地方,美观程度直接关联第一印象。
6. 赛后复盘:时间安排与团队协作
整个比赛最让我有感触的,不是某个算法有多巧妙,而是时间规划直接决定结果上限。
我们队的时间分配是:
- 第一天上午到第二天中午:集中精力做第一问+第二问,完成论文初稿中的模型部分;
- 第二天中午到第三天中午:完成第三问联合优化,并产出全部图表;
- 第三天下午:检查统一格式、补充灵敏度分析、修正摘要。
事实证明这个节奏非常关键。很多队伍第一天花了大半天纠结算法选型,第二天才发现时间不够用,最后三天通宵赶工,论文质量大幅下滑。
我自己的体会是,建模比赛的本质不是“解数学题”,而是在72小时内完成一次“仿真+工程+写作”的闭环。谁能尽早把每个子问题跑通、尽早开始写论文,谁就占据绝对主动。今年E题把路径规划、通信资源分配和多目标优化结合起来,正好命中了大厂和航天院所里“集群协同+资源调度”的典型场景,赛题本身非常有水平。希望这篇复盘能给准备下一届的朋友一些启发。