赛前总有人问我一句话:美赛D题能不能用一套现成套路直接套?我的回答是:能,但不能机械套。能的是,数据分析、综合评价、网络建模这条大骨架,近年的ICM·D题几乎是同一个配方;不能的是,如果只背模板、不理解赛题内部的决策逻辑,做到第三问就会崩——因为D题到后面问的不是“变量之间有什么关系”,而是“拿着这些关系你要替谁做什么决定”。
这篇文章专门写给2026年打算冲MCM/ICM的数学建模队伍。不是押题,也不存在谁能提前拿到真题;真正高效的做法,是把D题近五年反复出现的解法路径、代码骨架和论文呈现标准一次性备好。赛题揭晓后,你只需要把这个框架里的零件替换成当年的场景和数据,就能省下最宝贵的前半天。
1. 先搞懂D题的“脾气”:它是带数据的咨询题,不是纯算法题
1.1 ICM·D题和MCM前几题的本质差异
MCM的A题偏连续模型,B题偏离散模型,C题偏大数据洞察;ICM这边,E题通常围绕环境可持续,F题更多是政策与制度设计,而D题的命题传统是:挑一个贴近现实社会的复杂系统,给你一个足够开放的场景,再扔给你一堆不一定整齐的数据,让你用数学建模去回答“现状如何、为什么会这样、应该怎么办”。
所以D题的第一反应不该是“我要用什么高大上算法”,而是“这道题的服务对象是谁、决策变量是什么、数据能支撑到哪一步”。这点想不明白,后面所有模型都是空中楼阁。我用一句话概括:D题本质是一道带数据的咨询题,客户要的不是公式,是可执行结论。
这种题型的典型结构是三到五个小问,层层递进。第一问通常让你定义问题或者构建指标体系,第二问进入数据分析和建模,第三问开始做方案对比或情景推演,最后一问往往是“写一封给决策者的信”或者“给出政策建议”。很多队伍在第一问就拼命上复杂模型,结果后面没时间收口,这是最可惜的事。
1.2 从近几年D题里能读出三个共同点
以我能观察到的近年来ICM D题命题风格看,有三个共性特别明显。
第一,决策导向极强。题目很少让你纯算一个数,而是会问“哪座城市应该优先投资”“哪个方案最值得推广”,最终都要落到排序、选取、资源分配这些管理动作上。这不是偶然,ICM全称就是“跨学科建模竞赛”,它的隐藏要求是用数学语言去拆解跨学科的管理问题。
第二,数据形态多样。有的年份D题会直接附带大量数据;有的年份则需要你自己找数据,甚至需要你把不可量化的因素转化成可计算的指标。这就要求队伍里至少有人对数据处理、缺省值处理、标准化和去量纲化非常熟练。
第三,可视化和叙事权重非常高。D题的好论文几乎一定是“图多、表全、建议清晰”的。评委在有限时间里判断你的工作是否扎实,很大程度依赖你的图能不能让他三秒钟看懂你的结论。
1.3 别把“开放题”理解成“没标准”
有些队伍看到D题文字长、背景杂,就误以为这是开放性作文题,随便写写也能过。实际上D题的评分层次非常清楚。我理解大致有四层:第一层,模型是否真的在回答问题,而不是答非所问;第二层,建模过程有没有数据支撑,假设是否清晰;第三层,有没有做验证和灵敏度分析,而不是“算完就交”;第四层,结果是否可解释、建议是否具备可操作性。
这四层不是并列关系,而是层层淘汰。每年大量队伍挂在第一层和第四层上,中间两层反而拉开的是优秀和顶尖的差距。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 拿到题后的前90分钟:决定你能不能从容交卷
2.1 第一步不是找模型,而是把赛题翻译成“可计算的问题”
美赛总共四天多,真正的建模黄金时间是前12小时到24小时。最怕出现的情况是:开题两小时,队员已经在争论用神经网络还是随机森林。我必须泼一盆冷水:D题场景通常只有几百行到几万行数据,多数问题用线性回归、聚类、综合评价、网络指标就能解决,神经网络的大炮经常打不到蚊子。
开题后的前90分钟,应该全部用来做“赛题翻译”。具体操作是:把题目里的每一句话过一遍,凡是出现“评估、排序、识别、优化、比较、预测”这类动词,就圈出来;凡是出现定语性名词,比如“脆弱性、可达性、影响力、优先级、可持续性”,就单独列一张纸,追问一句:这个东西如果要用数据计算,该怎么定义?
举例来说,“某地区交通可达性”是一个抽象名词,但“该地区到最近医疗点的加权行驶时间倒数”就是可计算指标。D题高分论文和普通论文的分水岭,往往就在这一步:不管什么抽象概念,都能被你翻译成一行Python能跑出来的指标。
2.2 用一张“问题—数据—方法”三列锁定战场
我强烈建议团队在开题后合作用一个共享表格快速过题,三列分别是“题目要求”“我们需要什么数据”“可选方法”。下面给一个模板样式,实际使用时把赛题文字填进去即可。
| 题目问法常见类型 | 典型数据需求 | 常用方法方向 |
|---|---|---|
| 构建评价指标体系 | 各对象的多维属性、规模、投入产出 | 熵权法、CRITIC、TOPSIS、VIKOR |
| 分析对象之间的相互影响 | 关系型数据、网络邻接、流量数据 | 复杂网络中心性、社区发现、传播模型 |
| 预测某个宏观趋势 | 时间序列、面板数据 | 差分方程、灰色预测、回归、机器学习基线 |
| 给出资源配置或优化方案 | 成本、容量、约束条件 | 线性规划、整数规划、遗传/模拟退火 |
| 方案对不同场景的稳健性 | 参数区间、扰动假设 | 灵敏度分析与蒙特卡洛模拟 |
这张表做出来后,你们会立刻发现两个关键信息:一是哪些问题用现成工具就能完成,二是哪些问题存在数据缺口。数据缺口是D题最致命的问题,越早发现越主动。
2.3 四天时间怎么切
我建议的时间切法是这样的:第一天上午做问题翻译和数据侦察,第一天下午到第二天晚上完成主体模型和全部计算;第三天专门做灵敏度分析、模型改进和补图;第四天上午开始论文写作,留出最后几个小时统一检查摘要、图表编号、公式符号和参考文献。
这套节奏多年验证下来比较稳。它的核心逻辑是:把最烧脑的建模和计算放在精力最旺盛的前两天,后面几天哪怕发现思路要微调,也有充足缓冲。
3. D题的三大建模“武器”:网络、评价与演化怎么打组合拳
3.1 为什么D题特别爱考“系统与相互作用”
回看历年D题场景,不论是城市治理、交通物流、公共卫生还是文化传播,几乎都涉及大量主体之间的相互作用。城市之间彼此影响,机构之间存在协作网络,不同政策变量之间存在反馈回路。这种“复杂系统”底色,决定了单一回归模型无法撑起整篇文章。
所以备战D题,团队里至少要有一个人能熟练使用三套武器:网络模型负责描述“谁影响谁”、综合评价负责回答“谁更好”、演化或仿真模型负责回答“未来怎么变”。这三者顺序最好不要乱:通常是先用网络刻画结构,再用评价指标排出优先级,最后用演化模型验证方案在不同情景下的效果。
3.2 网络模型:先定义节点和边,再谈中心性
很多同学一上来就写代码算中心性,却忘了最关键的一步:节点是什么、边是什么、边的权重代表什么。这两种选择完全不同,结论也会完全不同。比如研究城市群协同发展,节点是城市,边可以是高铁往来班次、企业投资金额或者论文合作数量,不同定义回答的是完全不同的管理问题。
所以网络建模的第一步是写一段诚实的文字,明确说明节点和边的定义及数据来源。定义清楚后,常用指标有三个:度中心性反映“谁连接最多”,介数中心性反映“谁控制信息流通路径”,接近中心性反映“谁到其他节点最快”。如果边的权重表示联系强度,而你要计算最短路径时,通常要把强度取倒数当作“距离”,否则业务含义会颠倒。
有了中心性结果还不够,D题往往会要求你进一步做分层或分群。此时用社区发现算法,把网络划分成若干模块,再去看每个模块内部的主导因素是什么。这一步很有价值,因为它能让评委看到你不仅会算数,还能从算法结果里读出业务故事。
3.3 综合评价模型:熵权TOPSIS是D题性价比之王
综合评价是D题里出现频率最高的需求。只要题目里出现“评估A、B、C哪个更优”或“对若干对象进行优先级排序”,你就需要一套评价模型。
我为什么首推熵权TOPSIS?因为它比纯主观赋权更客观,又比单纯机器学习可解释性强很多。它的逻辑链条非常清晰:先用熵权法根据数据本身的信息量确定指标权重,再用TOPSIS计算每个方案与理想解的接近程度。评委看这种模型几乎不需要费力,就能理解你凭什么得出排序结论。
操作上有几个容易翻车的细节:第一,所有指标必须先做正向化处理,即“越大越好”的统一方向;第二,效益型指标用极差标准化即可,但成本型指标要先取倒数或做最大值减当前值;第三,熵权法计算时归一化矩阵不能出现零,要给对数项加上极小值保护,否则程序会直接报错。
3.4 演化与仿真模型:把“建议”落到“情景”上
D题最后一问经常需要回答“如果采取某项措施,未来会怎么变化”。这种问题不能只靠静态排序,需要给一个动态的演化逻辑。如果变量随时间连续变化,可以用微分或差分方程,比如传染病式的扩散模型;如果情景比较复杂,可以用多智能体仿真或离散事件仿真。
对建模比赛而言,我不建议在仿真上过度堆砌复杂度。评委要看的不是你写了多少行模拟代码,而是你的演化规则是否贴合题目背景、是否有依据、参数的初始值是否经过敏感性检验。一个规则透明、代码只有一百行但逻辑自洽的仿真,往往比一个封装过度的复杂仿真更能拿到分。
我见过不少队伍在第四问用了一大套系统动力学软件,做了漂亮到天花乱坠的图,但参数来源说不清楚,灵敏度也不做,最后结果被评委一推就问倒。演化模型的本质是“在假设条件下推演结果”,所以必须把假设条件全摆到桌面上。
3.5 组合拳的典型连接方式
如果今年D题继续沿用“描述现状—诊断原因—给出方案—验证效果”的套路,建模组合可以这样安排。
| 题问 | 推荐打法 | 输出物 |
|---|---|---|
| 第一问 | 指标体系建设+熵权TOPSIS | 排序结果,并解释排序合理性 |
| 第二问 | 复杂网络+社区发现 | 关键节点清单、分群特征、可视化 |
| 第三问 | 多方案评价或最优化模型 | 最优方案、对比表格、资源分配建议 |
| 第四问 | 演化模型/仿真+灵敏度分析 | 不同情景下的预测曲线与稳健性结论 |
这套组合几乎能覆盖D题绝大多数考法。具体赛题可能改名换面,但只要把每个子任务对号入座,建模阶段就不会慌乱。
4. 没有现成数据的D题,怎么“制造”合理数据而不失真
4.1 先穷尽官方数据,再考虑构造指标
D题有时候会主动附数据,但更多时候是“半开放”状态:题目给了背景和方向,默认你自己找数据。对于没有数据做支撑的队伍,第一反应不是闭门造车,而是去检索统计年鉴、政府开放数据平台、国际组织数据库、学术论文附录这些渠道。
找数据也要有目标感,不要打开一个网站就开始漫无边际下载。回到第2部分那张“问题—数据—方法”表,每一列数据都对应一个具体问题,按图索骥效率最高。如果赛题场景是中文语境,优先查国家和省市统计年鉴;如果场景是国际化的,则用国际公开数据,记得在参考文献里写清楚数据来源、下载时间和口径说明。
4.2 实在找不到数据时,用“指标构造法”兜底
确实存在一种情况:你需要的变量没有任何公开数据,怎么办?这时候不要轻易放弃建模,而是使用“指标构造法”。所谓指标构造,就是用一个能观测到的数据去近似替代一个理论概念,并且在论文里把这种近似关系如实写清楚。
举个例子,如果题目要衡量“区域间信息联系强度”,你找不到直接数据,但可以用“两地互联网关注度”“论文合著数量”“企业分支机构数量”这些可观测替代变量来构造权重。这种做法的前提是:替代变量的业务逻辑必须说得通,并且通过灵敏度分析告诉评委,结论不会因为你换一种构造方式就完全改变。
4.3 构造数据必须配合灵敏度分析
凡是用了构造指标、主观评分、专家打分的队伍,最后都要补一张灵敏度分析的图。这是D题论文的“护身符”。
做法其实不复杂:对权重或关键假设施加一定范围的扰动,比如把权重上下浮动10%、20%,观察最终排序是否发生明显变化。如果排名依然稳定,说明你的结论是稳健的;如果某些对象的排名大幅波动,说明你的模型对参数敏感,这种情况下要么调整指标设计,要么在结论里给出“只有在X条件下,建议Y才成立”的条件式表述。评委非常吃这一套,因为它体现的是科学态度。
5. 可以直接改用的Python代码骨架:从CSV到结论
下面给出一套我常用的D题代码骨架,已经去掉具体赛题内容,留好接口。只要把数据文件路径和列名改成你们的数据,就能快速跑出中间结果。
5.1 数据清洗和标准化
python复制import pandas as pd
import numpy as np
df = pd.read_csv("data.csv", encoding="utf-8-sig")
print(df.shape)
print(df.isna().mean().sort_values(ascending=False))
# 数值列统一转为数值格式,非数值会被置为 NaN
num_cols = ["indicator_1", "indicator_2", "indicator_3"]
for col in num_cols:
df[col] = pd.to_numeric(df[col], errors="coerce")
# 删除关键列有缺失的行,其余列用均值或中位数填充
df = df.dropna(subset=["object_name"])
df[num_cols] = df[num_cols].fillna(df[num_cols].median())
# 极差标准化,用于后续综合评价
def minmax_scale(x):
return (x - x.min()) / (x.max() - x.min() + 1e-12)
df_norm = df[num_cols].apply(minmax_scale)
df_norm.columns = [c + "_norm" for c in num_cols]
如果某个指标是成本型,也就是越小越好,标准化前先做一次正向化变换:x = x.max() - x,再用上面的函数。
5.2 熵权法计算权重,配合TOPSIS打分
python复制def entropy_weight(X):
# X: 已经正向化并极差标准化后的二维数组
# 加极小值避免对数运算出现 log(0)
P = X + 1e-12
P = P / P.sum(axis=0)
k = 1.0 / np.log(P.shape[0])
e = -k * (P * np.log(P)).sum(axis=0)
d = 1 - e
w = d / d.sum()
return w
def topsis_score(X, weights):
# 计算加权矩阵
Z = X * weights
z_pos = Z.max(axis=0)
z_neg = Z.min(axis=0)
# 计算欧氏距离
d_pos = np.sqrt(((Z - z_pos) ** 2).sum(axis=1))
d_neg = np.sqrt(((Z - z_neg) ** 2).sum(axis=1))
score = d_neg / (d_pos + d_neg + 1e-12)
return score
X = df_norm.values
w = entropy_weight(X)
print("指标权重:", dict(zip(num_cols, np.round(w, 4))))
df["score"] = topsis_score(X, w)
df = df.sort_values("score", ascending=False)
print(df[["object_name", "score"]].head(10))
这段代码跑完后,你们就有了第一问最常见的核心输出:对象排序。下一件事是分析排序结果为什么合理,结合具体场景解释前几名和后几名之间的结构性差别。
5.3 网络中心性和社区发现
python复制import networkx as nx
from networkx.algorithms import community
# edge_df 至少包含三列:from, to, weight
# 如果是无权网络,weight 列全设成 1 即可
G = nx.from_pandas_edgelist(edge_df, "from", "to", ["weight"])
# 如果边权代表“关系强度”,计算最短路径类指标时要转为距离
dist = edge_df.copy()
dist["cost"] = 1.0 / dist["weight"]
G_dist = nx.from_pandas_edgelist(dist, "from", "to", ["cost"])
metrics = pd.DataFrame({
"degree": dict(G.degree(weight="weight")),
"betweenness": nx.betweenness_centrality(G_dist, weight="cost"),
"closeness": nx.closeness_centrality(G_dist, distance="cost"),
})
# 三种指标的量纲不同,先排名再取平均,得到综合重要度
rank_df = metrics.rank(ascending=False)
rank_df["composite"] = rank_df.mean(axis=1)
print(rank_df.sort_values("composite").head(10))
# 社区发现
communities = community.greedy_modularity_communities(G, weight="weight")
for idx, nodes in enumerate(communities):
print("community", idx, "size", len(nodes))
需要特别提醒的是,在计算介数中心性和接近中心性时,我额外构造了一个G_dist图,用“1/强度”作为距离。很多初学者直接拿强度算最短路径,代码虽然不报错,但含义就反了。
5.4 灵敏度分析的快速循环
python复制results = []
scale_list = np.arange(0.8, 1.21, 0.05)
for scale in scale_list:
w_tmp = w * scale
w_tmp = w_tmp / w_tmp.sum() # 重新归一化
score_tmp = topsis_score(X, w_tmp)
# 记录排名前五的对象是否发生变化
top5 = df["object_name"].iloc[np.argsort(-score_tmp)[:5]].tolist()
results.append({"scale": scale, "top5": top5})
for res in results:
print(res["scale"], res["top5"])
这段代码的本质是“权重抖动”,是灵敏度分析最简形式。论文里再用一条折线图展示不同权重缩放比例下前五名排名的漂移情况,稳得不行的同时,也让评委看到你们做了认真验证。
5.5 让图能直接放进论文的Matplotlib设置
python复制import matplotlib.pyplot as plt
plt.rcParams.update({
"font.sans-serif": ["SimHei", "Microsoft YaHei"], # Windows/Mac常见中文字体
"axes.unicode_minus": False,
})
fig, ax = plt.subplots(figsize=(8, 5))
ax.bar(df["object_name"].head(10), df["score"].head(10), color="#4C72B0")
ax.set_title("Top10对象综合得分")
ax.set_xlabel("对象")
ax.set_ylabel("TOPSIS得分")
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig("topsis_ranking.png", dpi=300)
plt.show()
美赛正文页数有限,图片必须是一张顶一张。每张图都要有title、轴标签、单位、数据来源或说明,这份功夫能直接体现在评委观感上。
6. 论文呈现与评委视角:D题拿O和拿M的差距往往在这三处
6.1 Summary是整篇论文的投资回报率最高的部分
美赛评委第一眼看的永远是Summary,这几乎决定了他们对整篇论文的初始印象。D题的Summary不能只写“我们用了什么模型”,而要写成一段完整的迷你咨询报告:背景一句话交代,问题一句话翻译,方法一句话概述,核心结论用两三句话给出,最后加一句给决策者的建议。
很多队伍在Summary里堆模型名,罗列“AHP、TOPSIS、灰色预测、支持向量机”,结果评委看完根本不知道你到底解决了什么问题。正确写法是用业务语言说结论,再用括号注明支撑模型。比如“我们识别出影响系统韧性的三个关键因子(基于熵权TOPSIS排序)”,这就比干写方法名强得多。
6.2 变量表、假设清单和参数表是“防杠神器”
D题论文篇幅一般在20页出头,可读性非常重要。我强烈建议正文一开始放一张变量符号表,把论文中出现的所有符号、业务含义、单位和来源列出。另外在模型章节前专门用一小节列假设清单,每条假设说明合理性。
这个习惯有两个作用:一是防止评委在阅读中迷失,二是防止评委质疑你“这个系数为什么这么取”。当你有清晰的参数表,评审质询时会发现你已经想到了他准备问的问题,这就是印象分。
6.3 高质量论文里的图和表必须自解释
我再强调一次可视化。D题的数据通常有地理分布、网络结构、时间趋势等维度,至少要有以下类型的图:一张数据概览图展示研究对象分布;一张网络或热力图展示结构特征;一张排序图展示评价结果;一张趋势或灵敏度图展示动态和稳健性。每张图的标题和注释要写到“读者不看正文也能独立看懂”的程度。
相反,很多队伍只会贴Excel默认样式截图,坐标轴没有标签,中文乱码,图内还残留着默认配色。这种细节在评委眼里代表的是团队态度的不严谨。哪怕是现成的Matplotlib默认样式,也要花十分钟手工调一下标题、字号和配色再放进论文。
6.4 常见踩坑清单
最后整理一份我审过不少论文后总结的D题高频问题,你可以把它当成交稿前的检查清单来用。
- 字数全花在模型介绍上,前两个问题没回答完整,后两个问题草草收尾。建议按题目分值分配篇幅。
- 指标体系随便构造,不说明为什么选这些指标,也不做相关性检查和重复指标剔除。
- 对网络题只画图不算数,没有给出任何一个量化结论。
- 所有结果都放正文,没有用附录承接细节,导致正文被大量表格撑爆。
- 引用文献不规范,数据没有来源说明,模型公式符号不统一。
- 忽略灵敏度分析,这是D题评奖中最常见的失分点之一。
每一条其实都可以在交稿前4小时用一轮分工检查解决,但需要有人在规划阶段就把“检查时间”预留出来。如果你们按照刚才的节奏,第四天上午就进入论文收尾,那么下午检查这些清单完全来得及。
我自己的经验是:美赛D题从来不是“谁的模型最复杂谁赢”,而是“谁把复杂问题讲得最清楚谁赢”。把问题拆明白、把数据用扎实、把结论说到位,哪怕你用的都是经典方法,也足够冲一个很有竞争力的奖项。希望这套思路和代码骨架,能帮你的队伍在2026年少走几步弯路。
