华为杯研赛F题全攻略:从数据预处理到多目标优化的代码实现与论文写作

华为杯数学建模F题
于 2026-10-02 06:11:34 修改
·本内容遵循CC 4.0 BY-SA版权协议

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做全套预处理,流程如下:

PYTHON
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler
 
# 读取数据
df = pd.read_excel('F题数据.xlsx', sheet_name='Sheet1')
 
# 缺失值处理
# 数值型用中位数填充,类别型用众数填充
num_cols = df.select_dtypes(include=[np.number]).columns
cat_cols = df.select_dtypes(include=['object']).columns
 
for col in num_cols:
df[col].fillna(df[col].median(), inplace=True)
for col in cat_cols:
df[col].fillna(df[col].mode()[0], inplace=True)
 
# 异常值检测(IQR法)
def detect_outliers(df, col):
Q1 = df[col].quantile(0.25)
Q3 = df[col].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
return df[(df[col] < lower) | (df[col] > upper)]
 
# 标准化
scaler = StandardScaler()
df[num_cols] = scaler.fit_transform(df[num_cols])

这段代码看起来简单,但有几个细节值得展开说。缺失值填充为什么用中位数而不是均值?因为F题的数据往往有偏态分布,均值容易被极端值拉偏,中位数更稳健。异常值检测为什么用IQR而不是3σ?因为3σ假设数据服从正态分布,而实际数据往往不满足这个假设,IQR是非参数方法,适用性更广。

还有一个容易被忽略的点:量纲统一。F题中不同指标的取值范围可能差好几个数量级,比如一个指标是百分比(0-100),另一个是金额(百万级),如果不做标准化,优化算法会被大量纲指标主导,小量纲指标的作用被完全掩盖。

2.2 优化模型的代码框架

F题的核心是优化问题,我一般用PuLP或Gurobi做建模求解。PuLP是开源的,适合中小规模问题;Gurobi性能更强,但需要许可证。对于研赛来说,PuLP基本够用。

PYTHON
import pulp
 
# 创建问题实例
prob = pulp.LpProblem("F题优化模型", pulp.LpMaximize)
 
# 定义决策变量
x = pulp.LpVariable.dicts("x", range(n), lowBound=0, cat='Continuous')
y = pulp.LpVariable.dicts("y", range(m), cat='Binary')
 
# 目标函数
prob += pulp.lpSum([c[i] * x[i] for i in range(n)])
 
# 约束条件
for j in range(m):
prob += pulp.lpSum([a[j][i] * x[i] for i in range(n)]) <= b[j]
 
# 求解
prob.solve(pulp.PULP_CBC_CMD(msg=0))
print("最优值:", pulp.value(prob.objective))

这段代码的关键在于决策变量的类型选择。连续变量用Continuous,整数变量用Integer,0-1变量用Binary。F题中经常出现“是否选择某个方案”这类决策,必须用Binary变量。如果错误地用了Continuous,求解结果可能出现小数,不符合实际意义。

约束条件的写法也有讲究。上面的代码用的是循环添加约束,当约束数量很大时(比如上千个),这种写法效率较低。更高效的方式是直接用矩阵形式:

PYTHON
import numpy as np
A = np.array([[...]]) # 约束系数矩阵
b = np.array([...]) # 约束右端项
prob += pulp.lpSum([A[j][i] * x[i] for i in range(n) for j in range(m)]) <= sum(b)

不过对于研赛的规模来说,循环写法完全够用,没必要过度优化。

2.3 多目标优化的处理策略

F题的第三问或第四问经常涉及多目标优化。多目标优化的核心难点在于目标之间的权衡。常见的处理方法有三种:

方法 原理 优点 缺点
加权求和法 将多个目标加权组合为单目标 实现简单,求解快 权重难以确定,无法找到非凸Pareto前沿
ε-约束法 保留一个主目标,其余转为约束 可以找到非凸前沿 需要预设ε值,计算量大
NSGA-II 基于遗传算法的Pareto前沿搜索 一次运行得到多个Pareto解 参数调优复杂,收敛速度慢

我的建议是:如果题目没有明确要求Pareto前沿,用加权求和法就够了,但要在论文中说明权重的确定依据(如熵权法、AHP法)。如果题目明确要求分析多目标之间的权衡关系,那就必须用NSGA-II或ε-约束法。

NSGA-II的Python实现可以用pymoo库:

PYTHON
from pymoo.algorithms.moo.nsga2 import NSGA2
from pymoo.problems import get_problem
from pymoo.optimize import minimize
 
algorithm = NSGA2(pop_size=100)
res = minimize(problem, algorithm, ('n_gen', 200), seed=1)
print("Pareto前沿:", res.F)

pymoo的好处是封装完善,几行代码就能跑出Pareto前沿。但要注意种群规模和迭代次数的设置,太小了收敛不到最优前沿,太大了跑得慢。一般种群规模取100-200,迭代次数取200-500比较合适。

2.4 结果可视化与论文图表制作

华为杯评审对图表的清晰度要求很高。我一般用Matplotlib做基础图,用Seaborn做统计图,用Plotly做交互图(但论文里只能放静态图)。几个关键点:

  • 配色:不要用默认的蓝色,用plt.cm.viridis或plt.cm.RdYlBu这类色盲友好的配色方案。
  • 字体:论文里中文用宋体,英文用Times New Roman,字号不小于8pt。
  • 分辨率:保存图片时dpi=300以上,否则打印出来模糊。
  • 图注:每张图必须有编号和标题,如“图1 不同参数下的优化结果对比”。
PYTHON
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
 
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x_data, y_data, 'o-', color='#2E86AB', linewidth=2, markersize=6)
ax.set_xlabel('迭代次数', fontsize=12)
ax.set_ylabel('目标函数值', fontsize=12)
ax.set_title('算法收敛曲线', fontsize=14)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('convergence.png', dpi=300)

提示:论文中的图表不要直接截图,一定要用代码生成后保存为高清图片再插入。截图的分辨率通常不够,打印出来会糊。

3. 论文写作的保姆级拆解

3.1 摘要怎么写才能拿高分

摘要是论文的门面,评审老师看的第一眼就是摘要。华为杯的摘要要求是一页纸以内,包含问题背景、方法概述、主要结果和结论。我见过很多队伍的摘要写得像引言,废话太多,关键结果一个没有。

高分摘要的结构应该是:

  1. 第一段:一句话点明问题背景,一句话概括本文做了什么。
  2. 第二段:针对问题一,用了什么方法,得到了什么结果(带具体数值)。
  3. 第三段:针对问题二,新增了什么约束,方法做了什么调整,结果如何。
  4. 第四段:针对问题三和四,简要说明方法和核心结论。
  5. 最后一段:总结全文的创新点和实际意义。

关键原则:每一问的结果都要有具体数值。不要写“得到了较好的优化方案”,要写“优化后总成本降低了23.7%,从原来的158万元降至120.5万元”。

3.2 模型建立部分的写作规范

模型建立是论文的核心章节,写作要点如下:

  • 假设条件:每条假设都要编号,并说明为什么做这个假设。比如“假设1:不考虑突发事件对供应链的影响,因为题目给定的时间窗口内无相关数据支持”。
  • 符号说明:用三线表列出所有符号及其含义,符号要统一,不要前面用$x$后面用$y$表示同一个变量。
  • 模型构建:先写目标函数,再写约束条件,每个公式都要有编号和文字解释。
  • 模型求解:说明用了什么算法、什么工具、什么参数设置。

公式的LaTeX写法示例:

LATEX
\begin{equation}
\min Z = \sum_{i=1}^{n} \sum_{j=1}^{m} c_{ij} x_{ij}
\end{equation}

其中$c_{ij}$表示从节点$i$到节点$j$的单位运输成本,$x_{ij}$为决策变量。

3.3 结果分析与敏感性分析的写法

结果分析不能只放一张表就完事,必须有解读、有对比、有讨论。我一般按以下结构写:

  1. 基准结果展示:给出最优解的具体数值。
  2. 与基准方案的对比:优化前vs优化后,用百分比说明改进幅度。
  3. 敏感性分析:改变关键参数(如成本系数、约束右端项),观察最优解的变化。
  4. 管理启示:从结果中提炼出对实际决策有指导意义的结论。

敏感性分析的代码实现:

PYTHON
import numpy as np
import matplotlib.pyplot as plt
 
param_range = np.linspace(0.8, 1.2, 20)
results = []
for p in param_range:
# 修改参数p,重新求解
result = solve_model(p)
results.append(result)
 
plt.plot(param_range, results, 's-', color='#A23B72')
plt.xlabel('参数变化比例')
plt.ylabel('最优目标值')
plt.title('敏感性分析')
plt.axvline(x=1.0, color='gray', linestyle='--')
plt.show()

3.4 附录代码的整理技巧

附录代码是评审老师检查你工作量的重要依据。整理原则:

  • 按问题分节:问题一代码、问题二代码……不要把所有代码堆在一起。
  • 加注释:关键步骤必须有中文注释,变量命名要有意义。
  • 可运行:附录代码必须是能直接跑的,不要放伪代码或片段。
  • 格式统一:用等宽字体,行号可加可不加,但缩进要规范。

我一般用listings宏包在LaTeX中插入代码:

LATEX
\usepackage{listings}
\lstset{
language=Python,
basicstyle=\ttfamily\small,
keywordstyle=\color{blue},
commentstyle=\color{green!50!black},
stringstyle=\color{red},
numbers=left,
numberstyle=\tiny,
frame=single,
breaklines=true
}

4. 常见问题与排查技巧实录

4.1 求解器报错与调试方法

问题一:PuLP求解返回Infeasible

这是最常见的问题,原因是约束条件互相矛盾,可行域为空。排查方法:

  1. 逐个注释掉约束,看哪个约束导致不可行。
  2. 检查约束的符号方向是否正确(<= vs >=)。
  3. 检查变量边界是否合理(如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 赛后复盘与能力提升

比赛结束后,不管成绩如何,都要做复盘:

  1. 把优秀论文找来对比,看别人的模型和写作比自己强在哪里。
  2. 把代码整理归档,标注哪些部分可以复用。
  3. 把踩过的坑记录下来,形成自己的“避坑手册”。

我个人的体会是,数学建模能力的提升不是线性的,而是阶梯式的。每次比赛都会遇到新问题,解决之后能力就上一个台阶。F题作为华为杯的经典题型,值得反复研究。把历年F题的优秀论文都读一遍,你会发现很多套路是相通的——数据预处理的方法、优化模型的框架、论文写作的结构,这些都可以迁移到新的题目中。

最后分享一个小技巧:比赛期间如果卡住了,不要死磕,先跳过去做其他问。很多时候你在做后面的问题时,会突然想到前面问题的解法。大脑在后台处理信息的能力比你想象的要强。

华为杯数学建模竞赛C题破题与建模全攻略:从思路拆解到论文写作
本文系统梳理华为杯研究生数学建模竞赛C题的破题逻辑、三层建模方法(基础/核心/扩展模型)、数据处理与MATLAB/Python求解技巧、可视化规范及论文写作要点。重点涵盖问题类型识别、合理假设构建、优化与预测模型选型、灵敏度与多目标分析、LaTeX排版与摘要撰写等关键技术环节,强调模型可实现性、结果可解释性与表达结构化。
weixin_30647065
337
数学建模竞赛全攻略:从入门到获奖的核心方法与实战技巧
本文系统阐述数学建模竞赛的全流程方法论,涵盖主流赛事(国赛、美赛)选择策略、3天标准参赛时间管理、三人角色协同机制(建模手/编程手/写作手),以及从问题分析、模型构建、求解检验到论文撰写的四步拆解法。重点强调模型适用性判断(机理驱动vs数据驱动)、Python/MATLAB求解工具选型、LaTeX科技排版实践、模型检验三板斧(灵敏度/误差/对比分析)及高分论文写作规范。
weixin_30591551
358
2022华为杯研究生数学建模大赛赛题,已解密
华为杯数学建模大赛的六个赛题分别以字母A至F命名,每个题目都具有鲜明的时代特征和技术挑战。让我们逐一探讨这些赛题可能涵盖的知识点:1. 2022年A题:此题可能涉及到大数据分析和预测模型的构建。
scycie
1121
研究生数学建模华为杯F题代码
【标题】"研究生数学建模华为杯F题代码"涉及的是在数学建模竞赛中,参赛者使用编程语言解决特定问题的过程。
脑花沾干料
1980
2023年华为杯数学建模竞赛赛题
【2023年华为杯数学建模竞赛赛题】涉及了多个领域的数学建模问题,旨在挑战参赛者的数学应用能力和创新思维。
HHCV
1489
2018华为杯数学建模赛题.zip
《2018华为杯数学建模赛题.zip》是一个包含多份数学建模与最优化课程期末大作业的压缩包。这个压缩文件是2018年华为杯数学建模竞赛的相关资源,旨在帮助参赛者理解和解决当年的竞赛题目。
Chris_ZhangMQ
1123
2020年中国研究生数学建模竞赛赛题(A-F).zip
2020年的华为杯研究生数学建模竞赛,无疑为参赛者提供了展现才华的平台。该竞赛共设置了A至F六个不同的赛题,覆盖了广泛的实际应用领域,包括自然科学、社会科学、工程技术等多个方面。
地之旅行者
2349
2019华为杯数学建模竞赛赛题数据集
2019年的华为杯数学建模竞赛吸引了众多参赛者,覆盖了从A题到F题的六个不同主题。每个题目都涉及到深入的数学模型构建和数据分析,挑战参赛者的理论知识与实践应用。
幽游白书207
354
2020华为杯数学建模大赛F题第一问
在2020年的华为杯数学建模大赛中,F题的第一问主要涉及了实际问题的数学模型构建,特别是利用Python编程语言来解决一个与物理现象相关的问题:如何实时计算和预测油箱中液体的质心位置。
Greetings_Wang
1577
hwcup:数学建模 2020 华为杯 F 题
【标题】"hwcup:数学建模 2020 华为杯 F 题" 指的是一个与数学建模竞赛相关的项目,可能是参赛者在2020年华为杯数学建模比赛中解决的问题F。
钟离舟
949
2023年华为杯研赛F题思路分析
【数学建模在强对流降水临近预报中的应用】2023年华为杯研究生数学建模竞赛F题聚焦于利用双偏振雷达数据改善强对流天气的临近预报。
阿拉伯梳子
220