简介:2021年全国大学生数学建模竞赛C题完整资料包,面向参赛选手、指导教师以及希望系统提升建模能力的高校学习者,内容覆盖题目理解、模型构建、算法实现、求解验证与结果分析等完整流程。压缩包内共27个文件,包含13个MATLAB脚本文件(.m)、10个MATLAB数据文件(.mat)和4个Excel表格(.xlsx)。其中脚本按题号拆分,对应各小问的求解代码;.mat文件保存运行产生的中间数据或结果;Excel表格为赛题原始数据及订购、转运方案结果,便于对照复现。资源压缩后仅996KB,轻量易获取。目前已有2310人学习下载,热度较高。借助这套资料,可以直接运行代码复盘2021年C题的建模思路,学习如何将数学理论转化为可执行的数值求解,掌握优化模型、数据清洗、结果分析等实用技巧,对备赛冲刺和日常进阶都很有帮助。
1. 先看一个扎心事实:2021年C题多数队伍在第一问就输了
很多人在备战国赛C题前,以为这道数学建模题考的是数据分析——毕竟附件里有几百家供应商、几百周的供货记录,画几张热力图、跑几个聚类就算了事。2021年C题恰恰相反:它考的是供应商评价体系和订购方案优化,数据清洗只是入场券,评价权重怎么定、0-1整数规划怎么建、损耗约束怎么加,才是决定能不能拿奖的分水岭。这篇备考笔记把考点分布和得分逻辑拆开讲:第一问怎么建评价体系、第二问怎么求最少供应商、第三四问怎么把损耗和转运装进模型,每一问都配真题答题思路和易错点,适合正在备战国赛C题或想补数据决策类建模题的人。
2. 考点拆解:从供货数据到评价体系,第一问的完整答题路径
2.1 读题定调:C题不是数据分析题,是评价加优化
2021年C题以生产企业原材料订购与运输为背景,表面上是给了一大堆历史供货数据,看起来要预测未来走势、做数据挖掘。但问题一的要求很明确:对供应商的供货特征进行量化分析,建立评价体系。翻译一下,就是要你给几百家供应商打一个合理、可复算的分数,并排出名次。问题二在此基础上选择最少的供应商,问题三引入转运损耗,问题四把订购和转运联合起来求最优方案。整道题的逻辑线是“评价—筛选—订购—转运”,每一步都以上一步的结果作为输入。所以读题阶段就要建立正确的判断:这是数据驱动决策类题目,不是纯数据分析题。如果先入为主去做聚类和趋势预测,就会得到一个“看起来很好看但接不上问题二”的模型,方向跑偏是每年大量队伍第一问失分的主要原因。
C题向来被看作算法门槛不高、建模意识要求很强的题型,高手和普通队伍的分差往往不在代码,而在拆解题目的能力。读题时不要急着看数据,先看四个问题要什么:第一问要排名,第二问要最少数量,第三问要加损耗后的方案,第四问要联合优化。把这个链条写在一张纸上,再去碰附件,你会发现每一步方法都是被上一步“逼”出来的,而不是拍脑袋选一个高级算法。
2.2 数据清洗的第一道坎:供货量不等于订货量
附件里记录的是供应商每周实际供货量,不是订货量,这是一道隐形的坎。把每一行数据当成“正常供货”直接求均值,相当于把少供、断供的周数也当作正常数据,评价指标会被带偏。建议清洗时逐家供应商生成六个字段,每个字段都对应一个评价维度,整理成下表:
| 字段 | 计算方式 | 对应评价维度 |
|---|---|---|
| 供货周次数 | 统计该供应商有实际供货的周数 | 活跃度 |
| 非零周均值 | 仅对供货量大于0的周求平均 | 供应能力 |
| 供货量标准差 | 全部周供货量的标准差 | 波动性 |
| 变异系数 | 标准差除以非零周均值 | 稳定性 |
| 断供次数 | 按题目定义的未供货周次数 | 连续性 |
| 单周最大供货量 | 供货量最大值 | 突发上限 |
六个字段里最容易出错的是变异系数。严格来说,变异系数的分母是均值,当某家供应商均值极小、标准差也小时,变异系数可能被异常放大,导致排名严重靠后。处理时先做一次分布检查,若均值过小就单独标记,不要让它挤掉正常供应商的稳定性得分。清洗过程中所有中间表都要保存,因为论文附页和评委复查都需要展示数据是怎么一步步变成指标的。这一步没有快捷方式,但做好了,后面所有模型的结果都站得住。
2.3 真题演练:问题一评价体系怎么答才稳
问题一的经典答法是从三个维度切入:供应能力、供应稳定性、供应连续性。供应能力用非零周均值或累计供货量衡量,稳定性用变异系数衡量,连续性用断供次数衡量。得分公式写成:总得分=α×能力得分+β×稳定性得分+γ×连续性得分。这里的α、β、γ是权重,常用的确定方法有熵权法、CRITIC法和AHP层次分析法,三种方法各有适用前提,下一章会做详细对比。
评分环节注意两点。第一,所有指标先做min-max标准化,并且方向要对:能力类指标越大越好,变异系数和断供次数是逆指标,标准化后要取反向处理。第二,权重不要只给一个计算结果,要写清计算过程和数据来源,最好附一张权重表。评委最想看到的是评价体系可复算、可解释,而不是一个输出排名的黑匣子。这里不建议上随机森林之类的机器学习方法算特征重要性——方法本身没问题,但评委验证你结果的成本太高,线性加权加熵权法已经足够支撑一篇拿奖论文。最后在论文里给出排名前二十的供应商表格,并在表格下方写一句结论,比如“排名靠前的供应商在供货能力和稳定性上均明显优于排名靠后的供应商”,让评价结果一句话就能被别人理解。
2.4 关键衔接:评价结果凭什么能直接进问题二
问题二要求确定最少供应商数量,如果第一问的排名只是好看、不能用来筛选,这道题就断档了。比较自然的做法:按得分从高到低把供应商逐家加入候选集合,每加一家就计算当前集合的周供货能力之和,当累计能力第一次超过企业每周需求量时,记下当前供应商数量。这个数量是“最少数量”的一个上界,但未必是最优解,因为有可能中间某几家能力极强,跳着选能让数量更少。严谨的做法是把筛选过程写成0-1整数规划,第3章会给出完整代码。
这里还需要注意一个实操细节:企业每周需求量是固定常数,但实际生产流程往往要留一定余量。你可以把约束写成累计能力≥需求量×1.1,让方案更稳健,并在论文里说明这个安全系数的取值理由。要建立的衔接意识是:排名前几十的供应商不等于最后选中的供应商,评价体系的功能是对候选集合排序,优化模型的功能是在这个集合里挑出真正最少的那一批。两件事分开做,论文的逻辑才完整,评委也能顺着你的思路一步步看懂。
3. 高频考点:评价权重、0-1整数规划与订购转运的建模套路
3.1 权重方法对比:熵权、CRITIC、AHP该用哪个
权重方法是问题一的高频考点,三种方法对比:
| 方法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 熵权法 | 根据指标信息熵差异确定权重 | 客观、可复算 | 指标相关性高时权重失真 | 指标间相关性较弱 |
| CRITIC法 | 综合标准差与相关系数定权 | 兼顾波动性与冲突性 | 计算较繁琐 | 指标间相关性明显 |
| AHP层次分析 | 两两重要性判断构造矩阵 | 解释性强、评委友好 | 主观性强 | 维度少、想突出理由 |
选择建议:先把六个清洗字段标准化,再算相关性矩阵。相关性普遍较低时,直接用熵权法,客观且好解释;相关性较高时,用CRITIC法,因为它把指标之间的冲突也纳入了权重计算。AHP更适合作为辅助验证,比如用熵权法得到权重后,再用AHP检验权重排序是否符合常识,两个结果互相印证,论文的说服力会强很多。还有一点经常被忽略:权重算出来不是直接就能用,要对异常权重做说明。比如某个指标熵权接近0,说明它区分度太低,要考虑是否合并进其他指标,而不是硬塞进总分拉低整体可信度。
3.2 真题演练:问题二的最少供应商数量怎么求
问题二的标准建模框架是:目标函数为最小化供应商数量,约束条件是每周产能需求必须被满足。抽象之后是一个集合覆盖问题。先按第一问排名做贪心累加得到一个可行上界,再用0-1整数规划求最优。如果数据集比较大、求解变慢,可以先对排名前100的供应商做精确求解,剩余供应商作为后备不参与变量生成,这个剪枝操作要在论文中写明理由,评委会认可这种工程化处理。
订购量分配是另一个小考点:总能力满足需求不等于每周都恰好够用,还需要回答“向每家供应商订多少”。常规做法是让被选供应商按能力占比分摊每周需求量,同时保留一部分缓冲。若个别供应商单周供货量波动较大,可以用其历史最大值作为订购上限,防止方案在实际执行时靠一张纸根本走不通。求解完成后,把被选供应商名单和能力占用情况做成表格,放在论文正文里,评委最关心的就是你到底选了多少家、这几十家能不能支撑全周需求。
3.3 代码实战:用Python写0-1整数规划求解问题二
import pandas as pd import pulp # 读取附件1,字段:supplier_id 供应商编号,week 周序号,volume 当周实际供货量 df = pd.read_excel("附件1.xlsx") # 用非零周均值作为每家的周供货能力,0供货的周不参与平均 cap = df[df["volume"] > 0].groupby("supplier_id")["volume"].mean() # 企业每周产能需求,题目给定 D = 28200 # 建立0-1整数规划模型 prob = pulp.LpProblem("min_suppliers", pulp.LpMinimize) x = {s: pulp.LpVariable(f"x_{s}", cat="Binary") for s in cap.index} # 目标函数:被选中的供应商数量最少 prob += pulp.lpSum(x[s] for s in cap.index) # 约束条件:被选供应商的周供货能力之和 >= 每周产能需求 prob += pulp.lpSum(cap[s] * x[s] for s in cap.index) >= D prob.solve() selected = [s for s in cap.index if x[s].value() > 0.5] print("最少供应商数量:", len(selected)) print("选中供应商:", selected)代码逻辑说明:x_s是0-1决策变量,取值1表示这家供应商被选中;目标函数是这些变量的和,也就是供应商数量;约束中cap_s乘x_s,含义是只有被选中的供应商才把自己的能力累加进总供给。cap用的是非零周均值,这是常用做法,但并不是唯一选择。如果数据中有极值周,建议换成中位数或0.75分位数,并把结果放在灵敏度分析里,说明均值设定下最优数量是N家,中位数设定下是N加1家,这样反而能体现模型稳健性。
实际求解时如果变量太多跑不动,可以考虑两阶段:先用贪心法拿一个可行集合,再用0-1规划只在这个集合的邻域内做局部最优搜索。论文里要写明你用了哪种求解器、求解时间多少、是否达到全局最优,这些信息评委都会看。不要觉得这是小事,很多论文就因为在求解器说明里含含糊糊被扣了分。
3.4 问题三的损耗约束:订购量要除以(1-损耗率)
问题三把运输环节加入模型,核心是一个容易记混的公式。记住物理链路:供应商发出订购量→转运商运输→企业实际收到订购量×(1-损耗率)。要让实际收到量满足每周产能需求,就得让订购量=需求量÷(1-损耗率),而不是需求量×(1+损耗率)。后者从数字上看差别很小容易蒙混过关,但思路是错的。严格推导是:设订购量为q,损耗率为r,企业实收q(1-r),令其等于需求D,解得q=D/(1-r)。例如某转运商损耗率0.2%,周需求28200立方米,则订购量约28256.5立方米,额外多订约56.5立方米。
论文里要把这个公式单独列出来,并给一个表格对比不同损耗率下的额外订购量,评委会认为你真的理解损耗发生在运输环节而不是生产环节。同时要注意,损耗率不是加在供应商能力上,而是加在订购端:同一家供应商供货能力不变,但企业为了覆盖损耗必须订更多,所以第三问的供应商选择结果可能和第二问不同。这个差异要主动写出来,这是问题三和问题二最本质的区别。
3.5 真题演练:问题四的转运方案怎么和订购方案联合优化
问题四是压轴题,特征是多层级变量。常见框架分四层:选供应商、定每周订购量、选转运商、定每周转运次数。决策变量对应四类:每家供应商是否被选中的0-1变量、每周订购量的连续变量、每家转运商是否启用的0-1变量、每周转运次数的整数变量。目标函数可以写成损耗最小化与转运次数最小化的加权组合。
约束条件必须覆盖:每周实际到货量不低于产能需求、每家转运商每周最多运输次数上限、单次运输容量上限、供应商周供货能力上限。这里有一个非常容易被忽略的点:问题四的订购量和转运量必须拆成两个环节分别建模,先算“订多少才能补上损耗”,再算“这些量分配给哪几家转运商运”,两个环节不准合并成一个系数,否则你没法回答“转运方案具体是什么”这个问题。
时间紧张时,固定问题二选出的供应商集合,只优化转运分派,也能拿到主要分数。关键是让评委看到你有能力把两层决策放进同一个框架,哪怕为了可解性做了简化,也比东一块西一块强。如果还想往上冲,可以做一组对比实验:分开优化与联合优化的结果差距有多大,差距越大,说明你联合建模的价值越大,这往往就是加分点。
4. 易错点:五个让成绩掉档的常见错误
4.1 只给排名,不给可复算过程
错在很多队伍直接贴出前几十家供应商名单,没有交代指标怎么定义、权重怎么得到。原因在于:评委无法判断这份排名是模型算出来的还是拍脑袋排的,题目要求的“建立评价体系”就完全落了空。正确做法是:把六个字段、三个维度、权重计算结果、得分公式全部用表格呈现,再随机挑一家供应商,在论文正文里演示一遍从原始数据到最终得分的完整计算过程。比如某家供应商近五年供货数据如何变成非零周均值、变异系数如何算出、标准化后三个维度得多少分、加权求和后排在第几名。只要评委花两分钟能复查一家,你的可信度立刻拉满。
4.2 把周均值当成供应商能力上限
错在能力评估直接使用全部周数的平均值,某家供应商偶尔一周爆发,均值被拉高,后面优化模型就把这家选进来了。原因在于:优化模型假设每周都能拿到这个量,但实际供货波动可能让订购方案在多数周都完不成,模型结果根本不可行。正确做法是:用非零周中位数或0.75分位数做保守估计,并把均值设定下的结果显示在灵敏度分析里,注明“两种设定下最优供应商数量之差不超过x家”,说明你的结论对能力估计不敏感。这样评委不仅看到你会建模,还看到你意识到数据波动对模型的冲击。
4.3 损耗公式方向算反
错在把订购量写成需求量×(1+损耗率)。原因在于:实际到货量是订购量×(1-损耗率),按错误公式算出来到货量会严格小于需求。用数学推导检验:若错误地令订购量等于D(1+r),则到货量等于D(1+r)(1-r)=D(1-r²),永远小于D,属于系统性缺口。当损耗率只有0.2%时缺口很小容易被忽略,但思路错就是错。正确做法是:列出平衡方程需求=订购量×(1-损耗率),反解订购量,论文里写清这一步推导,再给一个算例验证,方向一旦对了,问题四的转运方案才能接得住。
4.4 把排名Top供应商全部选上
错在问题二直接把得分前几十家供应商整体放进订购方案,没有回答“为什么是这几十家而不是更少”。原因在于:题目问的是最少数量,给一个可行方案只能拿过程分,最优性完全没有论证。正确做法是:按第一问排序做一个贪心上界,再用0-1整数规划求解最小数量,最后做一个剔除检验——逐一去掉被选中供应商,若去掉任意一家就供给不足,说明当前集合已是最小集合。把这个检验结果写进论文,哪怕只有一句话,评委就能确认你是真的在求“最少”,而不是碰巧选了一批高分供应商。
4.5 图表与正文脱节,评委不知道图在表达什么
错在堆了大量热力图、折线图、散点图,正文里却没有一句话引用图的结论。原因在于:竞赛阅卷时间有限,评委不会帮你从图里提取信息,无结论的图反而挤占了有效篇幅。正确做法是:每张图后面紧跟一句结论句,比如“图3显示排名前20的供应商贡献了大部分供货量,说明评价结果与供货集中度基本一致”。图内还要标记关键位置,比如最优方案在折线上的位置、供应商排名曲线的拐点,让评委一眼看到这张图存在的意义。图表是论据不是装饰,这一点想清楚,论文的阅读体验会完全不同。
5. 冲刺方法:72小时分工与摘要四句式写法
5.1 72小时时间分配:先定输出,再选模型
拿到题后前三个小时不要碰代码,先把四个问题的输出要求写在纸上:问题一要供应商排名和评价体系,问题二要最少供应商数量和每周订购方案,问题三要考虑损耗重选供应商和订购方案,问题四要订购与转运的联合方案。四个输出写清后,再倒推用什么模型。后面的时间可以这样分配:第4到第12小时做数据清洗、字段生成和指标计算;第13到第24小时完成问题一评价体系及论文;第25到第36小时做问题二0-1规划并调试;第37到第48小时做问题三损耗公式和问题四转运模型框架;第49到第60小时补灵敏度分析、作图、检查约束遗漏;最后12小时写摘要、统一格式、核对数值。
这个节奏的关键是第一天不要沉迷画图。见过太多小组前12小时在做相关性热力图,第二天发现自己做的不是题目要的东西,血泪教训。数据清洗阶段宁可慢一点也要把每个字段的统计口径想清楚,后面所有模型都建立在这个基础上,地基歪了楼再高也是危楼。
5.2 摘要四句式:一句话一个得分点
摘要用四句话结构,可以让评委在30秒内抓住全部要点:
| 句子 | 作用 | 写法示例 |
|---|---|---|
| 第一句 | 点明问题与总体思路 | 针对生产企业原材料订购与运输问题,构建了基于供货能力、稳定性和连续性的供应商评价体系 |
| 第二句 | 给出核心模型与方法 | 采用熵权法确定指标权重,并建立以供应商数量最小为目标、以周产能需求为约束的0-1整数规划模型 |
| 第三句 | 量化核心结果 | 求得最少需选择供应商x家,订购方案满足每周产能需求 |
| 第四句 | 点出亮点 | 通过损耗平衡方程将运输损耗折算入订购量,实现订购与转运的联合优化 |
这个模板不是让你照抄,而是逼着你在动笔前就把模型和结果想清楚。四句话写不出来,说明模型核心还没立住。我第一次参加全国赛时,摘要写了一大段流水账,把数据预处理每个人都写了三行,评阅意见第一行就写着“摘要未突出模型与结果”。从那以后,我每次建模都强制自己在论文动笔前先把这四个句子写出来,写不顺就回去改模型,直到第四句能自然收住为止。希望帮到你。
本文还有配套的精品资源,点击获取