1. 美赛B题到底在考什么:近五年命题规律与选题策略
带过几届队伍,看过几十篇O奖论文之后,我越来越觉得美赛B题在国内参赛者心里被严重低估了。很多人默认“B题就是连续型题目,拿数据建模就行”,结果到赛场上才发现完全不是这么回事。先说一个关键判断:从2020年到2025年,B题的命题风格已经从“经典连续模型”转向“交叉学科+现实决策+数据驱动”的综合题,纯靠套一个微分方程模型就想拿奖的时代早就过去了。
举个例子,近五年B题涉及过无人机编队、水资源配置、灾害应急响应、区域经济与资源协调这类话题,每一个都不是单纯数学问题,而是“物理约束+资源调度+多目标优化”的混合体。命题组特别喜欢给一个真实场景,塞给你一部分数据,再让你补充假设,最后要求你回答几个决策层面的问题——比如“如何分配”“如何调度”“如何选址”。所以B题的核心考核点,不是你会多少种算法,而是你能不能把一个现实问题翻译成数学语言,再翻译回决策建议。
再直白一点,B题是“应用型优化题”的大本营。你几乎每次都能用上规划模型、排队模型、网络流模型或者动态规划,然后配合启发式算法去求解大规模实例。这和C题那种纯数据挖掘、机器学习套路很不一样。C题可以用XGBoost跑分数,B题必须让评审看到你的建模逻辑是闭环的——从假设到目标函数,从约束到求解策略,从灵敏度分析到政策建议,每一环都要对得上。
这就引出一个决策问题:队伍到底该选哪道题? 我的建议是,如果你的队伍里有一个人擅长运筹学或算法设计,另一个人英文读写能力强,那B题就是最稳妥的选择。因为B题的数据量通常没有C题那么爆炸,物理意义比D题更直观,赛题语言不像E题和F题那么“社科化”,入门门槛适中,但上限很高——做出彩了就是O奖水平。
选B题之前还要做一件事:把前五年的B题摘要都读一遍。不是读正文,而是只读摘要,看人家是怎么组织“问题重述—模型建立—求解方法—结果分析”这一段话的。两三小时就能看完,性价比极高。你会发现优秀论文的摘要有一个共同点:第一段说问题,第二段给出整体建模思路,第三段按小问逐条给出方法和结果,最后用一两句话说结论和建议。这个结构是美赛评选的硬通货,后面写论文时直接照这个结构走。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 一套通用建模框架:从读题到交稿的完整工作流
很多队伍前24小时都在原地打转,反复读题、反复讨论、反复推翻,最后时间全浪费了。我自己的经验是:把4天的赛程切分成四个阶段,每个阶段有明确交付物,队伍就不会乱。
第一阶段(前6小时):理解问题与信息盘点。 拿到题目后,先别讨论算法,全队一起逐句读题至少两遍,然后用“问题关键词表”的方式整理:题目里反复出现的关键词是什么?给定了哪些数据?哪些条件是可变的?哪些信息需要我们自己假设?这个表做完,你对题目的理解会比大部分队伍清晰得多。
第二阶段(第6-24小时):建立核心模型框架。 这里是建模的主战场,先要求“所有小问都能被同一个核心模型框架解释”,再逐步细化。美赛B题的第二问、第三问往往是在第一问基础上加约束、加目标、加不确定性,所以核心框架的抽象能力决定了后面顺不顺利。
第三阶段(第24-60小时):求解、分析与迭代。 拿到初步结果后,先做可视化,不要急着写论文。先看结果是否符合直觉,如果某个数值严重偏离常识,优先检查模型假设和数据预处理,而不是调算法参数。这个阶段最容易掉进去的坑是“为了用算法而用算法”,明明贪心算法够用,非要上遗传算法,结果调参调到崩溃。
第四阶段(第60-96小时):论文写作与排版冲刺。 数学建模比赛的结果是论文,不是代码。我甚至见过求解平平无奇但论文写得很漂亮的队伍拿到M奖,也见过模型设计得很好但论文表达混乱的队伍只拿了S奖。所以最后一天半,至少两个人全力写论文,一个人持续补齐图表和附录。
这套流程看着简单,但能做到的队伍其实不多。主要原因是大多数队伍没有“交付物意识”——每个阶段结束之后没有形成一个可以被检查的产出物。建议每个阶段结束时,队长把所有产出物发到群里:第一阶段发问题理解表,第二阶段发模型框架图(手画或PPT画都行),第三阶段发图表和中间结果,第四阶段发论文草稿。这样大家的进度永远对得上。
这里还要特别强调一个B题特有的问题:题目里的“小问”往往是递进的,但正文里的“前置假设”可能要到后面的小问才暴露出来。比如第一问让你设计一个最优调度方案,看起来很简单,但第二问突然加了资源有限、设备故障概率、成本预算等约束。所以第一阶段读题时,千万不要只看第一问就开干,必须把全题所有小问都读完,在理解问题表里记录“潜在关联假设”,给后续留好接口。
3. 范例论文结构拆解:评委希望看到的八个部分
美赛论文结构其实非常固定,但不代表你可以随便写。我拆解过不下30篇O奖和F奖论文,发现它们不管题目风格如何,都稳定保持着八个核心组成部分。
第一部分是Summary(摘要),这一页是评委对你论文的第一印象,也是最终评分权重中最高的单项之一。O奖摘要的行文逻辑基本是:第一句点明问题背景和建模目标;第二到第三句说明核心模型名称与关键假设;中间用三到五句话按小问逐一说明“对什么构建了什么模型,用什么方法求解,得到什么关键数值结果”;最后一句写明方案建议。摘要的篇幅在一页之内,不要超出。这里有句忠告:摘要永远不要写“we use these methods to solve the problem”这种废话,评委要看的是“which model for which problem, solved by which algorithm, got what number”。
第二部分是Restatement and Assumptions(问题重述与假设)。问题重述不是抄题目,而是用你自己的语言重新组织问题场景,显示出你“读懂并抓住了问题核心”。接下来的假设列表必须逐条说明“为什么做这个假设”“它简化了什么或者带来了什么限制”。比如无人机调度里假设“所有无人机速度恒定”,是为了规避复杂的空气动力学;而在敏感性分析阶段,又会反过来讨论如果假设放宽,结果会如何变化。这样的假设写法才是合格的。
第三部分是Notation(符号表)。美赛的评委非常看重符号系统的清晰程度。一个做法是用三列表格:符号、含义、单位。全篇的公式都必须严格使用这张表里的符号,不允许中途临时换符号,否则评委直接给你扣分。
第四部分是Model Establishment(模型建立)。这里要写清楚三样东西:决策变量是哪些,目标函数是什么,约束条件有哪些。每一个约束都要用文字说明一次“它代表什么场景下的什么限制”,然后再用公式表达。公式后面还要跟一句中文(或英文)解释,不能光秃秃一堆编号公式。
第五部分是Model Solution(模型求解)。求解部分必须包含“算法选择理由”和“求解流程”,即使你用最基础的模拟退火,也要写明为什么选择它,以及你迭代了多少次、参数怎么设置的。这里建议放一个“伪代码块+核心代码片段”的组合。评委虽然不会真的运行你提交的代码,但清晰的代码结构会极大提升专业感。
第六部分是Analysis(结果分析与验证)。光说“模型求出了最优解”远远不够,必须做三件事。第一,关键结果的可视化(折线图、热力图、三维图等);第二,对结果进行敏感性分析,逐个扰动关键参数看结论是否稳定;第三,和简化基准模型做对比,说明强化模型“比基准方案好在哪里”。
第七部分是Strengths/Weaknesses(模型评价)。注意,不要只写优点,也千万不要写“Our model has no weakness”。合理的写法是:指出模型因为数据限制或计算开销,暂时忽略某些因素,并说明在什么条件下可以扩展。这种坦诚的学术态度非常加分。
第八部分是References(参考文献)。格式统一、引用规范就好。需要特别提醒的是,美赛不强制要求你真的读过每一篇参考文献,但引用内容必须和正文对应,不要堆砌和全文毫无关系的文献。
4. 配源码的完整实操:以LRP问题为例的建模与Python实现
光讲框架太虚,下面用一个非常典型的B题风格问题——“物流网络中的设施选址与路径规划(Location-Routing Problem, LRP)”——来串一遍完整实操。这类问题恰好也是美赛B题的常客,既能体现优化模型,又能自然引入启发式算法。
4.1 问题设定
假设有一个灾后应急物资调配场景:有若干候选物资仓库的位置、若干个需求点(受灾社区)的位置和需求量,已知车辆的装载容量上限,要求你选择开设哪些仓库,并规划从仓库到需求点的配送路径,使得“总建设成本+总运输成本”最低。
这其实就是“选址+车辆路径”的组合优化问题,拆开看分别是经典的设施选址问题(FLP)和带容量约束的车辆路径问题(CVRP)。两个问题单独解都不算难,难在联合优化——你选的仓库位置会直接影响路径长度,而路径长度又会反过来决定哪个仓库选址更优。
4.2 建模思路
把问题抽象成数学语言:
- 决策变量1:
x[j]表示是否在候选点j开设仓库,取值0或1 - 决策变量2:
y[i][j]表示需求点i是否分配给仓库j,取值0或1 - 决策变量3:
z[j][i][k]表示车辆从仓库j出发,路径上第k个访问点是否为需求点i
目标函数写作:
Min ∑_j fixed_cost[j] * x[j] + ∑_j ∑_i ∑_k travel_cost[j][i][k]
约束包括:每个需求点必须被服务一次;每个仓库覆盖的总需求量不能超过容量限制;车辆路径的载重不能超过车辆容量;只有被选中的仓库才能分配需求点。
对于小规模问题(比如需求点在20个以内),可以直接用整数规划求解器跑出精确解。对于更大规模的问题,就跑一个“先聚类、后路径”的启发式:先用K-Means按地理位置把需求点聚成几簇,每个簇对应一个仓库;再用贪心算法或者最近邻算法规划每辆车从仓库出发的配送顺序。这个做法不是理论最优,但在比赛场景下足够你拿到一个合理且有说服力的结果。
4.3 Python代码框架
下面的代码使用pulp库实现一个简化版的LRP模型,可以直接替换成自己的数据跑通。如果你还没有安装pulp,在终端运行pip install pulp即可。
python复制import pulp
import numpy as np
# ------------- 参数区 -------------
# 需求点坐标(示例数据,实际使用时替换为自己的数据)
demand_points = [(10, 20), (25, 35), (45, 30), (20, 50), (55, 15)]
demand = [5, 8, 6, 9, 4] # 每个需求点的需求量
# 候选仓库坐标
depot_candidates = [(15, 25), (40, 40)]
fixed_cost = [100, 120] # 仓库固定建设成本
capacity = 15 # 仓库容量上限
num_demand = len(demand_points)
num_depot = len(depot_candidates)
# 计算距离矩阵
def dist(p1, p2):
return np.sqrt((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)
distance = np.zeros((num_depot, num_demand))
for j in range(num_depot):
for i in range(num_demand):
distance[j][i] = dist(depot_candidates[j], demand_points[i])
# ------------- 建模区 -------------
prob = pulp.LpProblem("Facility_Location", pulp.LpMinimize)
# 决策变量
x = pulp.LpVariable.dicts("Open", range(num_depot), cat="Binary")
y = pulp.LpVariable.dicts("Assign",
((j, i) for j in range(num_depot) for i in range(num_demand)),
cat="Binary")
# 目标函数:固定成本 + 运输成本
prob += pulp.lpSum(fixed_cost[j] * x[j] for j in range(num_depot)) + \
pulp.lpSum(distance[j][i] * y[j, i] for j in range(num_depot) for i in range(num_demand))
# 约束1:每个需求点必须被分配给一个仓库
for i in range(num_demand):
prob += pulp.lpSum(y[j, i] for j in range(num_depot)) == 1
# 约束2:只有开设的仓库才能分配需求点
for j in range(num_depot):
for i in range(num_demand):
prob += y[j, i] <= x[j]
# 约束3:仓库容量约束
for j in range(num_depot):
prob += pulp.lpSum(demand[i] * y[j, i] for i in range(num_demand)) <= capacity * x[j]
# ------------- 求解区 -------------
prob.solve()
# 输出结果
print("求解状态:", pulp.LpStatus[prob.status])
cost = pulp.value(prob.objective)
print("总成本:", round(cost, 2))
for j in range(num_depot):
if pulp.value(x[j]) > 0.5:
assigned = [i for i in range(num_demand) if pulp.value(y[j, i]) > 0.5]
print(f"仓库 {j} 开设,覆盖需求点: {assigned}")
这段代码的核心逻辑在于三个约束——“每个需求点必须被覆盖”“只有开设的仓库才能服务”“需求量总和不能超过容量”。跑通之后,你可以试着增加一个“每个仓库服务需求点的配送顺序”变量,把模型扩展成“选址+路径”一体化的完整LRP。扩展后模型规模会变大,这时候就需要改用Gurobi或者Google OR-Tools,它们的整数规划求解性能比pulp强不少。Gurobi对学术用途是免费的,赛前建议提前申请好许可证。
4.4 启发式算法的补充
如果题目给的数据量特别大(比如数千个需求点),精确求解器就不可能在一个小时内跑完了。这时候最简单的做法是分两步。
第一步,先用KMeans把需求点聚类,聚类数就是仓库数。每个簇的中心位置可以作为仓库的初始位置;如果你还有候选仓库点,就直接把每个需求点分配给距离最近的候选仓库,形成初始方案。第二步,对每个仓库服务的需求点集合,用“节约算法”或者“最近邻法”规划一条配送回路,计算总路径长度。
我比赛中实际验证下来,这个“聚类+贪心”组合方案虽然不求全局最优,但胜在速度快、稳定性好,而且完全够你在论文里做“与精确解的对比实验”。更妙的是,你可以先在小规模数据上用精确解算出最优值,再用启发式跑一次,两者对比就能写出一段漂亮的“模型验证”段落——这对美赛评委来说是非常有说服力的。
5. 可视化与图表设计:让你的论文从“能看”升级到“耐看”
美赛提交的论文有一个硬性要求:信息传递量极大,但页数有限。图表就是你压缩信息的最佳工具。我甚至可以说,在模型公式水平差不多的前提下,图表质量直接决定你是M奖还是F奖。
先说工具。画示意图用PPT或者draw.io,一张清晰的问题场景图能极大帮助评委理解你的建模背景。画数据图表用Python的matplotlib或seaborn,尽量避免用Excel直接生成图表,因为Excel的默认样式在美赛排版里显得很业余。画流程图可以用draw.io或visio,算法流程、建模框架图直接决定论文前半部分的可读性。
关于配色,美赛论文不要用五颜六色的大红大紫。推荐统一用“白色底+一种主色+一种辅色”的配色方案,比如主色用深蓝,辅色用橙色,所有图表的配色保持一致。配色一致性的视觉效果远胜于每张图都好看但风格完全不同的效果。
关于图表的类型选择,记住一个原则:想展示趋势用折线图,想展示分布用直方图或箱线图,想展示空间位置用散点图或热力图,想展示组成结构用堆叠柱状图,想展示算法收敛过程用迭代曲线图。有些队伍明明想表达“不同方案在不同参数下的成本对比”,结果画了一张三维曲面图,看起来炫酷,但读者完全读不出有用信息。图表的核心目标永远是“让信息一眼可见”,不是“让评委觉得你很厉害”。
还有一个很容易被忽视的细节:每张图都要有一个直观的标题,并且正文中要出现“如图X所示”的引导语句。图号和图题写在图下方,表号和表题写在表上方。图和表的编号要按出现顺序排列,不存在“附录里单独编号”的特殊情况。这些是格式细节,但评委一天要看几十份论文,格式凌乱的论文会在心理上被扣分。
如果你时间充裕,强烈推荐做一张“全文核心结果总览图”,把题目各个小问的输入、模型、算法、关键输出数值放在一张横向或纵向的流程图里。这张图放在引言或摘要附近,评委扫一眼就能对整个解决方案建立全局印象。很多O奖论文都有这样一张图,因为它承载了“把复杂故事压缩成一页”的功能。
6. 避坑清单与常见问题排查实录
最后这部分是我最想写的,因为每一届都有队伍踩同样的坑。把这些坑整理成一份实用清单,比赛时直接对照排查。
问题一:只建模型,不计算结果数值。 这是最致命的错误。美赛B题几乎每个小问都要求“给出具体方案/具体数值”。有些队伍建模写了一整页,结果部分却只有“we solve it by simulated annealing”和一张模糊的迭代曲线,没有给出任何一个“到底选择哪个仓库、总成本是多少”的实质性结果。评委想看的是决策结论,不是算法汇报。
问题二:摘要写得像目录。 “In this paper, we first propose a model, then propose another model, finally propose a third model.”这种摘要等于没写。摘要必须写清楚“模型核心思路+关键求解方法+最重要的定量结果+建议结论”。写得好的摘要,是那种只看摘要不看全文,也能复述出“你做了什么、得到什么”的文字。
问题三:假设列表过于敷衍。 有些队伍写的全是“假设天气良好”“假设数据无误”这种废话,毫无建模价值。好的假设有两种:一是简化型假设(“无人机飞行速度恒定,忽略加减速过程”),二是边界性假设(“研究范围内道路网络保证连通”)。每写一条假设,都要能说出它如何影响模型设计。
问题四:代码和论文完全是两回事。 提交的源码要能跑通,而且要保证核心函数和论文中描述的算法流程一致。评委如果发现你论文里写“用遗传算法求解”,但没有提交任何遗传算法相关代码,信任度会大打折扣。建议赛前统一整理一次代码目录结构,包含data/、src/、results/三个文件夹,并在README.md里写明运行方式。
问题五:最后两小时还在改模型。 4天的比赛,到第90小时之后绝对不应该再进行模型层面的改动。最后几个小时只做三件事:检查摘要是否准确反映正文内容、统一全文格式、检查参考文献和附录是否完整。任何新想法,如果第90小时还没落地,就果断放弃。
问题六:全队只有一个人会写英文论文。 美赛的正文需要用英文写作,而且篇幅在20页左右。如果只有一个人能写,这个人到后期会非常累,写作质量也会直线下降。更好的分工方式是:建模的同学提供公式和图表,编程的同学提供结果和可视化,写作的同学负责把所有素材组织成连贯的英文论文。三个人都要参与写作过程的校对,至少过三遍全文。
我在实际比赛中还有一个心得:把审题时整理的关键词做成一张“术语对照表”,中英文各一列,放在共享文档里。比如“约束”对应“constraint”,“容量限制”对应“capacity limitation”,“决策变量”对应“decision variable”。写作时随时查询,能减少大量来回修改术语的时间。
关于提交文件的清单,建议赛前就列一个checklist:主论文PDF、summary sheet、完整源码压缩包、数据文件、可视化图片、README说明文档、参赛队伍信息编号确认。每一项都按照官方要求命名和压缩,避免因为格式问题被取消资格。
最后分享一个我在多次带队中反复验证的经验:美赛B题的高分秘诀不是模型的复杂度,而是“问题理解-建模-求解-分析”这条链路的完整度。每个环节都做到70分以上,最终论文就不会低于M奖;如果某一环能做到95分(通常是结果可视化或者摘要写作),就具备冲F奖和O奖的潜力。希望这份思路整理能帮你少走弯路,比赛时专注于真正重要的事情。祝顺利。
