华为杯研赛F题全攻略:从数据预处理到多目标优化的代码实现与论文写作
1. 从F题看研究生数学建模的破题逻辑
1.1 这道题到底在考什么
每年华为杯研赛的F题都有一个很鲜明的特点:题目背景往往来自真实的工程场景或产业痛点,数据量大、约束条件多、开放性强。2026年这道F题也不例外。从题目给出的信息来看,核心考察的是多约束条件下的优化决策能力,同时要求参赛者具备数据处理、模型构建、算法实现和结果验证的完整闭环能力。
很多队伍拿到题目后的第一反应是“这题要用什么模型”,这个思路其实是有问题的。正确的顺序应该是:先搞清楚题目要你做什么决策,决策变量是什么,约束条件有哪些,目标函数怎么定义,然后再去匹配模型。F题的四个问题通常是递进关系——第一问打基础,第二问加约束,第三问引入不确定性或动态因素,第四问做综合优化或敏感性分析。这个递进逻辑决定了你不能孤立地看待每一问,后面的问题往往需要复用前面的中间结果。
我见过太多队伍在第一问就卡住,原因是他们试图一步到位建一个“完美模型”,结果参数标定做不下去,数据预处理也没做好,后面三问全部崩盘。所以我的建议是:第一问用最简单的可行模型先跑通全流程,哪怕精度差一点也没关系,关键是拿到一个baseline,后面再逐步迭代。
1.2 四问之间的递进关系拆解
根据历年F题的出题规律和2026年题目的具体描述,四问的递进关系大致如下:
- 第一问:通常要求建立基础模型,在理想条件下求解最优方案。这一问的核心是变量定义要清晰,目标函数和约束条件要写规范。很多队伍在这一问丢分不是因为模型不够复杂,而是因为变量定义混乱、约束条件遗漏。
- 第二问:在第一问基础上引入新的约束或改变目标函数。这一问的关键是识别新增约束对可行域的影响,很多时候第一问的最优解在第二问直接变成不可行解,需要重新搜索。
- 第三问:引入随机性、动态性或不确定性。这一问往往需要从确定性优化转向随机优化或鲁棒优化,蒙特卡洛模拟是常用手段。
- 第四问:综合前三问的结果做全局优化或敏感性分析,有时还会要求给出政策建议或管理启示。
理解了这个递进关系,你在写代码和论文的时候就能做到心中有数——每一问的代码不是孤立的脚本,而是一个可以复用的模块化系统。
1.3 为什么大多数队伍在F题上翻车
翻车的原因我总结下来无非三类:
第一类是数据预处理没做好。F题的数据通常有缺失值、异常值、量纲不统一等问题,如果不做清洗直接建模,结果根本不可信。我见过有队伍用原始数据直接跑回归,R²只有0.3,后来做了异常值剔除和标准化,R²直接上到0.85。
第二类是模型选择与问题不匹配。比如题目要求做多目标优化,有队伍非要用单目标加权法,权重怎么定都说不清楚,最后结果被评委质疑。正确的做法是根据问题特性选择合适的多目标优化算法,如NSGA-II或MOEA/D。
第三类是论文写作不规范。华为杯的评审非常看重论文的规范性和可读性,公式编号、图表标注、参考文献格式这些细节都会影响得分。很多队伍模型做得不错,但论文写得像实验报告,最后与奖项失之交臂。
注意:F题的评审标准中,模型的合理性占40%,结果的准确性占30%,论文的规范性占30%。三者缺一不可。
2. 代码实现的核心模块与关键细节
2.1 数据预处理模块的完整实现
数据预处理是整个建模流程的地基。F题的数据通常以Excel或CSV格式给出,字段多、量大,手动处理不现实。我一般用Pandas做全套预处理,流程如下:
这段代码看起来简单,但有几个细节值得展开说。缺失值填充为什么用中位数而不是均值?因为F题的数据往往有偏态分布,均值容易被极端值拉偏,中位数更稳健。异常值检测为什么用IQR而不是3σ?因为3σ假设数据服从正态分布,而实际数据往往不满足这个假设,IQR是非参数方法,适用性更广。
还有一个容易被忽略的点:量纲统一。F题中不同指标的取值范围可能差好几个数量级,比如一个指标是百分比(0-100),另一个是金额(百万级),如果不做标准化,优化算法会被大量纲指标主导,小量纲指标的作用被完全掩盖。
2.2 优化模型的代码框架
F题的核心是优化问题,我一般用PuLP或Gurobi做建模求解。PuLP是开源的,适合中小规模问题;Gurobi性能更强,但需要许可证。对于研赛来说,PuLP基本够用。
这段代码的关键在于决策变量的类型选择。连续变量用Continuous,整数变量用Integer,0-1变量用Binary。F题中经常出现“是否选择某个方案”这类决策,必须用Binary变量。如果错误地用了Continuous,求解结果可能出现小数,不符合实际意义。
约束条件的写法也有讲究。上面的代码用的是循环添加约束,当约束数量很大时(比如上千个),这种写法效率较低。更高效的方式是直接用矩阵形式:
不过对于研赛的规模来说,循环写法完全够用,没必要过度优化。
2.3 多目标优化的处理策略
F题的第三问或第四问经常涉及多目标优化。多目标优化的核心难点在于目标之间的权衡。常见的处理方法有三种:
| 方法 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 加权求和法 | 将多个目标加权组合为单目标 | 实现简单,求解快 | 权重难以确定,无法找到非凸Pareto前沿 |
| ε-约束法 | 保留一个主目标,其余转为约束 | 可以找到非凸前沿 | 需要预设ε值,计算量大 |
| NSGA-II | 基于遗传算法的Pareto前沿搜索 | 一次运行得到多个Pareto解 | 参数调优复杂,收敛速度慢 |
我的建议是:如果题目没有明确要求Pareto前沿,用加权求和法就够了,但要在论文中说明权重的确定依据(如熵权法、AHP法)。如果题目明确要求分析多目标之间的权衡关系,那就必须用NSGA-II或ε-约束法。
NSGA-II的Python实现可以用pymoo库:
pymoo的好处是封装完善,几行代码就能跑出Pareto前沿。但要注意种群规模和迭代次数的设置,太小了收敛不到最优前沿,太大了跑得慢。一般种群规模取100-200,迭代次数取200-500比较合适。
2.4 结果可视化与论文图表制作
华为杯评审对图表的清晰度要求很高。我一般用Matplotlib做基础图,用Seaborn做统计图,用Plotly做交互图(但论文里只能放静态图)。几个关键点:
- 配色:不要用默认的蓝色,用
plt.cm.viridis或plt.cm.RdYlBu这类色盲友好的配色方案。 - 字体:论文里中文用宋体,英文用Times New Roman,字号不小于8pt。
- 分辨率:保存图片时
dpi=300以上,否则打印出来模糊。 - 图注:每张图必须有编号和标题,如“图1 不同参数下的优化结果对比”。
提示:论文中的图表不要直接截图,一定要用代码生成后保存为高清图片再插入。截图的分辨率通常不够,打印出来会糊。
3. 论文写作的保姆级拆解
3.1 摘要怎么写才能拿高分
摘要是论文的门面,评审老师看的第一眼就是摘要。华为杯的摘要要求是一页纸以内,包含问题背景、方法概述、主要结果和结论。我见过很多队伍的摘要写得像引言,废话太多,关键结果一个没有。
高分摘要的结构应该是:
- 第一段:一句话点明问题背景,一句话概括本文做了什么。
- 第二段:针对问题一,用了什么方法,得到了什么结果(带具体数值)。
- 第三段:针对问题二,新增了什么约束,方法做了什么调整,结果如何。
- 第四段:针对问题三和四,简要说明方法和核心结论。
- 最后一段:总结全文的创新点和实际意义。
关键原则:每一问的结果都要有具体数值。不要写“得到了较好的优化方案”,要写“优化后总成本降低了23.7%,从原来的158万元降至120.5万元”。
3.2 模型建立部分的写作规范
模型建立是论文的核心章节,写作要点如下:
- 假设条件:每条假设都要编号,并说明为什么做这个假设。比如“假设1:不考虑突发事件对供应链的影响,因为题目给定的时间窗口内无相关数据支持”。
- 符号说明:用三线表列出所有符号及其含义,符号要统一,不要前面用$x$后面用$y$表示同一个变量。
- 模型构建:先写目标函数,再写约束条件,每个公式都要有编号和文字解释。
- 模型求解:说明用了什么算法、什么工具、什么参数设置。
公式的LaTeX写法示例:
其中$c_{ij}$表示从节点$i$到节点$j$的单位运输成本,$x_{ij}$为决策变量。
3.3 结果分析与敏感性分析的写法
结果分析不能只放一张表就完事,必须有解读、有对比、有讨论。我一般按以下结构写:
- 基准结果展示:给出最优解的具体数值。
- 与基准方案的对比:优化前vs优化后,用百分比说明改进幅度。
- 敏感性分析:改变关键参数(如成本系数、约束右端项),观察最优解的变化。
- 管理启示:从结果中提炼出对实际决策有指导意义的结论。
敏感性分析的代码实现:
3.4 附录代码的整理技巧
附录代码是评审老师检查你工作量的重要依据。整理原则:
- 按问题分节:问题一代码、问题二代码……不要把所有代码堆在一起。
- 加注释:关键步骤必须有中文注释,变量命名要有意义。
- 可运行:附录代码必须是能直接跑的,不要放伪代码或片段。
- 格式统一:用等宽字体,行号可加可不加,但缩进要规范。
我一般用listings宏包在LaTeX中插入代码:
4. 常见问题与排查技巧实录
4.1 求解器报错与调试方法
问题一:PuLP求解返回Infeasible
这是最常见的问题,原因是约束条件互相矛盾,可行域为空。排查方法:
- 逐个注释掉约束,看哪个约束导致不可行。
- 检查约束的符号方向是否正确(
<=vs>=)。 - 检查变量边界是否合理(如
lowBound=0但约束要求变量为负)。
问题二:Gurobi许可证报错
研赛期间Gurobi会提供临时许可证,但需要提前申请。如果报错“No license found”,检查环境变量GRB_LICENSE_FILE是否指向正确的许可证文件。
问题三:求解时间过长
F题的规模可能很大,求解时间可能超过预期。应对策略:
- 设置求解时间上限:
prob.solve(pulp.PULP_CBC_CMD(timeLimit=300)) - 使用启发式算法替代精确算法(如遗传算法、模拟退火)
- 对问题进行分解,化为多个子问题分别求解
4.2 论文格式被扣分的典型场景
| 扣分项 | 具体表现 | 正确做法 |
|---|---|---|
| 公式无编号 | 文中引用“上面的公式” | 每个公式都要有编号,如式(1) |
| 图表无标题 | 直接放一张图,没有图注 | 图下方写“图1 xxx”,表上方写“表1 xxx” |
| 参考文献格式混乱 | 有的有年份,有的没有 | 统一用GB/T 7714格式 |
| 页码缺失 | 论文没有页码 | 页脚居中加页码 |
| 摘要超页 | 摘要写了两页 | 严格控制在一页以内 |
4.3 时间分配与团队协作建议
研赛通常是四天三夜,时间分配建议:
- 第一天上午:读题、讨论、确定选题(F题通常是六题中选一题)。
- 第一天下午到第二天上午:数据预处理、第一问建模求解。
- 第二天下午到第三天上午:第二问、第三问建模求解。
- 第三天下午:第四问、敏感性分析。
- 第三天晚上到第四天上午:论文写作、图表制作。
- 第四天下午:检查、排版、提交。
团队分工建议:一人主攻建模,一人主攻编程,一人主攻论文。但不要完全割裂,建模的要懂代码,编程的要懂模型,写论文的要懂前两者的工作。
注意:提交前一定要检查文件格式和命名规范,每年都有队伍因为提交格式错误被取消资格。
5. 从F题延伸出去的一些经验
5.1 代码复用的模块化设计
如果你打算长期参加数学建模竞赛,建议把常用的代码模块封装成函数库。比如:
data_preprocess.py:数据清洗、缺失值处理、标准化optimization.py:线性规划、整数规划、多目标优化visualization.py:常用图表模板sensitivity.py:敏感性分析框架
这样下次比赛时可以直接调用,节省大量时间。我自己的代码库已经积累了三年,现在拿到新题基本上半天就能搭好框架。
5.2 模型创新点的挖掘思路
华为杯评审很看重创新性,但创新不一定是发明新算法。以下几种方式都算创新:
- 组合创新:把两个已有方法结合起来解决新问题。
- 改进创新:对已有算法做针对性改进(如改进遗传算法的交叉算子)。
- 应用创新:把某个领域的方法首次应用到另一个领域。
- 数据创新:引入外部数据增强模型的说服力。
5.3 赛后复盘与能力提升
比赛结束后,不管成绩如何,都要做复盘:
- 把优秀论文找来对比,看别人的模型和写作比自己强在哪里。
- 把代码整理归档,标注哪些部分可以复用。
- 把踩过的坑记录下来,形成自己的“避坑手册”。
我个人的体会是,数学建模能力的提升不是线性的,而是阶梯式的。每次比赛都会遇到新问题,解决之后能力就上一个台阶。F题作为华为杯的经典题型,值得反复研究。把历年F题的优秀论文都读一遍,你会发现很多套路是相通的——数据预处理的方法、优化模型的框架、论文写作的结构,这些都可以迁移到新的题目中。
最后分享一个小技巧:比赛期间如果卡住了,不要死磕,先跳过去做其他问。很多时候你在做后面的问题时,会突然想到前面问题的解法。大脑在后台处理信息的能力比你想象的要强。