
每年四月的MathorCup数学应用挑战赛都是建模圈子里绕不开的一仗。很多同学一看到“B题完整论文”“参考代码免费分享”这种标题就两眼放光但真正拿到手的资料要么是残缺的草稿要么是东拼西凑的代码连能不能跑起来都是问题。我连续参加了三届从国赛省二到研究生数模国一对这类竞赛论文和代码的“水分”再清楚不过。这篇内容我打算把自己压箱底的MathorCup B题参赛经验整体复盘一遍从拿到赛题后如何快速判断题型、分配时间到论文每一小节怎么布局才能让评委觉得“这组人是真的做完了建模”再到参考代码里到底该放什么样的代码才能兼顾跑得通和答辩解释最后是提交前后最容易踩的坑和降AI率、查重那些事。无论你是第一次参赛的小白还是冲国奖的老手这篇文章都值得你收藏到比赛结束。1. 赛前准备与选题判断拿到B题后的第一个小时决定你的上限1.1 MathorCup B题的真实定位MathorCup全称是MathorCup数学应用挑战赛它的题目风格和国赛、美赛都不太一样。相比国赛的“厚数据、多小问”MathorCup更看重从实际问题中抽象模型的能力尤其是应用数学工具解决行业问题的完整链条。B题通常是优化类或评价决策类问题数据量不大但问题描述里藏了不少约束条件和隐性需求。以我参赛的经验来看B题大体上逃不出这几类生产调度优化、路径规划、资源分配、综合评价排名。2025年的B题延续了这个传统题目背景是制造业场景下的生产排程问题要求给出能在规定周期内完成的调度方案同时考虑机器寿命、能耗、订单优先级等多个目标。这类题目的特点是“门槛低、天花板高”——谁都能套个线性规划或者遗传算法上去但真正拉开差距的是你如何处理多目标冲突、如何把小问之间的逻辑串起来。1.2 快速选题与团队分工策略三人团队拿到赛题之后第一个小时绝对不要动手写任何代码。我和队友的固定流程是前30分钟各自独立通读所有题目用不同颜色笔圈出自己认为的关键约束和变量然后花20分钟讨论“这题本质是什么模型”最后10分钟确定分工、列出接下来的24小时进度表。有一个容易犯的错误是“看见数据就想着做数据清洗、画热力图”。B题虽然也会给制造数据但它不像C题那样以数据分析为核心它的数据更多是为了支撑优化模型中的参数比如单位时间能耗、机器故障概率、订单交付期限等等。所以拿到Excel表的第一时间应该思考的是“这些参数能不能直接读进优化模型”而不是“这组数据有没有相关性”。我们的分工方式比较固定队员A负责建模和论文中的模型推导部分队员B负责编程实现和结果可视化队员C负责数据整理、文献查找和论文排版。所有人每天早晚各开一次15分钟的站会同步进度、提出卡点。这里我特别想强调论文手绝对不能等到最后一天才开始动笔至少要提前半天开始搭框架否则最后一天的凌晨你一定会后悔。1.3 资源清单真正有用的资料只有这几样网上的MathorCup资料鱼龙混杂很多所谓“完整论文”其实是从知网下载的旧题论文甚至大作业。我参加比赛使用的核心资料其实很精简历年MathorCup或相近赛题如华为杯、五一数模的优秀论文5篇左右只看框架和摘要写法Python科学计算环境安装好numpy、pandas、matplotlib、scipy、ortools、pymoo这几个核心库一篇自己整理的LaTeX模板包含三线表、公式编号、算法伪代码的样式两三套“救急代码”比如遗传算法框架、模拟退火框架、熵权法、TOPSIS评价代码。我不建议大家赛前囤几十个G的视频课程和电子书因为比赛期间根本看不完。真正有价值的临时补充是针对性搜索某个具体算法的实现细节比如“带约束的NSGA-II Python代码”而不是从头啃一本算法书。2. 论文结构设计与写作顺序先让评委看懂“你们做了什么事”2.1 摘要是一切的开始也是一切的结束任何数学建模竞赛摘要都是评委最先看、也最认真看的部分。MathorCup B题论文的摘要页通常独立一页篇幅控制在一页之内要交代清楚“针对什么问题、建立了什么模型、用什么方法求解、得到什么结果、结果有什么改善或价值”。我的摘要写作套路是四段式第一段交代背景和问题实质用两三句话把生产调度问题翻译成“多约束条件下的多目标优化问题”第二段写模型一和方法比如“针对订单排产子问题建立了以总拖期时间最小和机器能耗最省为目标的混合整数规划模型采用改进遗传算法求解得到最优排产方案为XX”第三段写模型二和三如果用了评价模型或预测模型也要分别说清楚输入、输出、方法和核心结果第四段总结整个研究的特色和实际意义。这里要特别提一个容易让人丢分的细节摘要里出现的所有符号都必须在正文中定义清楚而且摘要中提到的数值结果一定得是模型真实跑出来的不能靠拍脑袋编。评委中有不少就是做运筹优化的你随便写一个“效率提升30%”这种没有任何推导过程支撑的数字反而会被当成破绽。2.2 问题分析、模型假设与符号说明“问题分析”这一节不需要写太长但逻辑要清晰。可以分小问逐条展开每小问要求什么、该问题在数学上属于什么类型、计划用什么工具处理。这里评委希望看到你们真的读懂了题目而不是把题目抄一遍。“模型假设”是很容易被忽视但影响很大的环节。好的假设能简化问题又不过分失真。我习惯把假设分成两类一类是数据层面的比如“在调度周期内各机器不发生非计划故障”“订单准备时间已包含在加工时间中”另一类是方法层面的比如“各订单之间不存在抢占式加工一台机器同时只能加工一个工件”。每个假设后最好附一句“该假设的合理性说明”让评委觉得你们的假设是有自主意识的。符号说明表一定要用三线表列出符号、含义、单位。这里有一个我踩过坑的教训同一篇论文里同一个符号绝对不能既表示“机器编号”又表示“某个惩罚系数”。如果变量实在太多可以用上下标区分但必须在符号表里统一说明否则评委很容易看晕印象分直接下降。2.3 建模与求解多目标优化问题的完整链条B题的核心部分通常聚焦在“如何把生产调度问题转化为可求解的数学形式”。我们的做法是走“决策变量—约束条件—目标函数—求解算法—结果分析”这条标准链路。以生产排程问题为例决策变量通常是一组0-1变量表示某个订单的第几道工序在哪台机器的第几个位置上加工。约束条件包括机器能力约束、工序先后约束、订单交期约束、非中断加工约束等。目标函数多目标时不要一上来就加权重求和因为权重很难定评委也会质疑。更推荐的方法是先用Pareto多目标优化找出非支配解集再结合熵权TOPSIS法从Pareto解集中选出最优折衷解。这个方法在2025年MathorCup B题的评阅中表现很好因为评委看到的不是一个拍脑袋的加权系数而是一套“先优化、再决策”的两阶段框架。当然如果时间不够或者问题规模较小直接线性加权并用粒子群或遗传算法求解也完全可以接受只要在灵敏度分析中把权重变化对结果的影响写清楚。3. 参考代码的实现思路哪些代码值得放进附录3.1 数据读取与预处理代码必放B题的数据往往没那么干净。我拿到赛题自带的Excel表后先用pandas做了一遍快速检查有没有缺失值、订单的工艺路线是否完整、每台机器的可用时段是否存在重叠。下面是一段我常用在预处理阶段的数据读取与清洗模板import pandas as pd import numpy as np # 读取订单和机器数据 orders pd.read_excel(data.xlsx, sheet_nameorders, header0) machines pd.read_excel(data.xlsx, sheet_namemachines, header0) # 简单检查缺失值和数据类型 print(orders.isnull().sum()) print(machines.isnull().sum()) # 加工时长转换为分钟统一时间单位 orders[process_time] pd.to_timedelta(orders[process_time]).dt.total_seconds() / 60 machines[available_start] pd.to_datetime(machines[available_start]) machines[available_end] pd.to_datetime(machines[available_end])这段代码在附录里放的意义不是展示技术难度而是告诉评委“我们的数据是经过认真处理后才进入模型的”。很多队伍直接手动清数据然后进模型虽然结果一样但缺了这种可复现性。3.2 核心优化算法框架建议放如果用遗传算法求解调度问题论文附录里的代码不需要完整到可以直接复制运行但一定要包含核心的编码、解码、交叉、变异函数。尤其是“如何将调度方案编码成染色体”这一部分是评委和答辩老师最关心的地方。我给出一个典型的基于任务排列的编码思路import random def init_population(pop_size, job_count): # 每个染色体是订单加工顺序的排列 population [] for _ in range(pop_size): chromosome list(range(job_count)) random.shuffle(chromosome) population.append(chromosome) return population def decode(chromosome, process_times, machine_avail): # 按染色体顺序调度到最早可用机器返回完工时间与能耗 schedule [] current_time 0 total_energy 0 for job_id in chromosome: start_time max(current_time, machine_avail[job_id % len(machine_avail)]) finish_time start_time process_times[job_id] schedule.append((job_id, start_time, finish_time)) total_energy finish_time - start_time return schedule, total_energy需要注意这个解码函数非常简化实际赛题中还要考虑订单有多个工序、工序有先后顺序、不同机器加工同一种工件的时间可能不同所以编码通常会从一维排列扩展成“工序序列机器分配”的二维结构。代码放附录时建议把关键注释写全让评委一看就明白你们的编码逻辑和物理含义对应关系。3.3 结果可视化和敏感性分析代码锦上添花可视化是很多队伍的弱项但又是论文的加分项。Matplotlib画甘特图的逻辑其实不复杂把每个订单的每道工序在对应机器上的开始时间和结束时间画成横向色块。甘特图画出来之后整个调度方案一目了然比甩一张Excel表有说服力得多。此外敏感性分析也是B题论文必须有的板块。通常会考察订单数量、机器数量或能耗权重变化对总拖期时间的影响。用循环批量跑模型把结果画成折线图或热力图。放这部分代码的好处是让评委觉得你们的结果不是孤立的而是有稳健性验证支撑的。4. 论文写作与排版避坑指南细节决定了评阅体验4.1 公式、图表与算法伪代码的规范化数学建模论文中公式必须用LaTeX排版不能用Word自带公式编辑器随手敲更不能用图片截图代替。公式要有编号且在正文中要引用“式(3)”而不是“下面的公式”。算法步骤建议用伪代码块呈现至少要包含输入、输出和每步操作让不熟悉编程的评委也能看懂你们做了什么。图表的题注规范同样重要。图题在图的下面表题在表的上面不要搞反。所有坐标轴必须有变量名和单位不要让评委看到一张“只有数据没有轴说明”的图。甘特图除了颜色区分不同订单之外最好在图上直接标注订单编号和开工时间。4.2 降AI率与查重你必须提前知道的事2025年之后数模竞赛对AI生成内容的审查越来越严格MathorCup也明确要求提交时附上AI使用报告甚至有些赛区还会做AIGC检测。因此论文写作要尽量避免大段由AI生成的“漂亮话”。我自己的策略是所有文字先手写底稿再用AI润色局部语法和连词而不是复制粘贴一整段AI回答。查重方面知网和维普都可能会用到所以不能用网络上直接下载的论文段落、论坛里的现成文字连摘要的套话也要自己写。有一个非常实用的降重技巧把“模型建立”这一节中的文字描述和数学推导结合起来用公式把话“说”清楚。比如与其用一大段中文描述“我们需要在满足机器容量约束条件下最小化订单总加权拖期时间”不如直接写一个数学模型然后逐行解释每一项的含义。这样一来重复率会明显下降而且学术规范性也更强。4.3 提交与打包的最后一小时比赛结束时总是会有队伍因为提交问题翻车。我建议提前一天完成初稿最后半天专门用来做格式检查和备份PDF版本是否打开正常、有无乱码附件压缩包是否包含全部代码和数据代码能否在当前环境直接运行至少要保证入口文件和main函数没问题队伍编号、页眉页脚是否正确摘要页是否独立成页。建议至少准备三个备份渠道队员各自的网盘、一个用于提交的邮箱附件、一个本地的独立文件夹。每隔2小时手动把最新版论文复制进去命名格式统一为“队号_b题_v3_0421_22时”。别嫌麻烦每年都有队伍因为一个文件名没改对导致提交版本混乱最后交上去的跟最后写出来的不是同一版。5. 常见问题排查与竞赛实操心得实录5.1 模型跑不出理想结果怎么办这是比赛过程中最让人崩溃的问题。有几次我凌晨三点盯着遗传算法的收敛曲线发现迭代到200代结果仍然很差。遇到这种情况优先检查的不是算法参数而是约束条件有没有冲突。很多调度问题跑不出可行解不是因为算法不行而是因为“订单的总加工时间超过了机器在周期内的总可用时间”。这种情况下应该回到数据层调整假设比如允许加班时段、允许部分订单延期并设置惩罚系数否则任何算法都白搭。还有一种常见情况是目标函数的量纲差异造成优化方向被某一个目标主导。比如能耗的数值范围是几万而拖期订单数的范围是个位数直接加权求和后算法几乎只优化能耗忽略了交期。这时需要先对每个目标做归一化处理或者用Pareto方法直接处理多目标而不是继续调权重。5.2 论文篇幅和内容安排上的权衡很多人担心论文页数不够于是拼命凑篇幅加一堆无关的数据探索截图。实际经验是论文总页数在25页以内为宜不含附录但每一页都要有信息量。如果模型已经够多没必要每个模型都长篇大论讲原理如果模型较少可以通过灵敏度分析、结果对比、模型推广来拓展深度而不是灌水。评委一天要看几十篇论文他们最怕的就是“内容很多但看了3页还不知道你们做了啥”的文章。5.3 优秀论文的“正确打开方式”网上能找到很多MathorCup优秀论文但直接当模板抄是最愚蠢的做法。我每次看优秀论文只看三样东西第一他们的摘要怎么组织关键词第二每个小问的衔接处怎么过渡第三他们在灵敏度分析部分选了什么参数做变化。至于具体的模型公式和代码几乎不用他们的思路因为赛题年年变别人的模型套过来大概率是水土不服的。真正高效的学习方法是“隔天复盘”比赛结束后的第二天拿出正式论文对照自己赛前的计划和过程中的卡点写一份500字左右的参赛总结记录下哪些地方因为准备不足浪费了时间。这份总结比任何资料都有价值因为下一场比赛你会更清楚自己的节奏。写在最后的一点个人经验三年参赛下来我最深的体会是数学建模比赛真正考核的不是谁的算法最高深而是谁能在有限时间内把一个实际问题用数学语言讲清楚并给出可信、可复现的结果。MathorCup B题尤其如此它不会要求你用多么前沿的理论但会逼着你想清楚“每一行约束到底在模拟生产现场的什么规则、每一个目标到底对应决策者的什么诉求”。所以如果你们队伍现在还在焦虑“模型太简单会不会被评委会看不起”我的建议是先把手头的模型做到逻辑清晰、结果稳定、论文讲透再考虑加复杂度。优秀论文很多不是赢在模型花哨而是赢在每一步都有理由、每一个结果都有解释。祝各位都能在今年的赛场上交出一份自己满意的答卷。