数学建模竞赛C题解析:基于时序预测与优化模型的蔬菜定价补货决策
2026/9/19 19:47:43 网站建设 项目流程

1. 赛题背景与核心挑战解析

每年全国大学生数学建模竞赛的C题,向来是区分度最高、最考验综合建模能力的“硬骨头”。2023年的C题也不例外,它没有像A题那样给出一个明确的物理或工程背景,也没有像B题那样偏向于数据统计分析,而是将目光投向了农业生产中一个非常具体且现实的问题——蔬菜类商品的自动定价与补货决策。这个题目一出来,很多同学的第一反应可能是“这不就是个简单的预测和优化问题吗?”,但真正深入进去,你会发现它巧妙地融合了时间序列预测、运筹学优化、数据清洗与特征工程,甚至还有一点博弈论的影子。它考察的不仅仅是你会不会用ARIMA或者LSTM,更是你如何将一个模糊的商业问题,抽象成一个清晰、可解的数学模型,并给出有说服力的决策依据。

这道题的核心,是要求参赛者扮演一个生鲜零售商的“智能决策大脑”。你手头有过去四年(2019-2023)每天数百种蔬菜的销售流水、批发价格和损耗数据。你的任务有两个:第一,为未来一周(2023年7月1-7日)的每种蔬菜制定每日的补货量和定价策略;第二,在满足一系列复杂约束(如单品销售总量限制、总品类销售配额、利润率要求、损耗控制等)的前提下,尽可能提升商超的收益。这听起来像是一个标准的“预测-优化”两阶段模型,但难点恰恰在于这两个阶段的耦合与反馈。你的定价会影响销量,销量又反过来影响你的补货决策和最终的损耗,而损耗率又会影响你的成本与利润。这是一个动态的、带有不确定性的决策闭环。

很多队伍在这里容易陷入一个误区:把预测和优化完全割裂。先不管三七二十一,用历史数据训练一个预测模型,得到未来一周的“预期销量”,然后把这个预期销量当作一个固定值,扔进优化模型里去算补货和定价。这种做法忽略了“价格弹性”——你的定价策略本身就会改变需求曲线。一个更贴近现实的思路是,你需要建立一个需求函数,将销量表示为价格、时间、季节、促销等因素的函数。然后,你的优化模型不是在给定销量的情况下求最优解,而是在求解一个均衡点:在这个价格和补货量下,预测出的销量恰好能使你的利润最大化,并且满足所有约束。这才是本题建模的“灵魂”所在。

2. 数据预处理与特征工程的深度思考

拿到题目附件中的销售流水表,第一感觉可能是数据量不小,但比较规整。然而,魔鬼藏在细节里。有效的数据预处理是后续所有模型工作的基石,处理不好,预测结果会失之千里。

2.1 异常值与缺失值的处理策略

销售数据中必然存在异常值,比如因系统错误记录的天量销售(如9999千克),或因门店盘点、节假日歇业导致的销量为0或极低。对于明显的错误记录,直接视为缺失值处理。但对于节假日或歇业导致的零值,则需要谨慎区分。一个实用的方法是结合附件中的“批发价格”数据以及常识进行判断:如果某天某种蔬菜的销量为0,但当天有批发价格记录,且前后几天都有正常销售,那么这很可能是门店原因(如盘点)导致的真实零销售,应予以保留。如果销量为0且当天无批发价,则可能是数据缺失。

对于缺失值的填补,不能简单地使用整体均值或前后插值。蔬菜销售具有强烈的周期性和趋势性。我们团队当时采用了“同类项填补法”:首先,将蔬菜按保存周期、销售模式(如叶菜类、根茎类、茄果类)进行粗分类。对于某个单品某天的缺失值,优先用该单品在同一星期几的历史同期(如前几周的同一天)的销量均值进行填补。如果历史同期数据也缺失,则使用该分类下其他单品在同一天的销量均值作为参考。这种方法比简单的时间序列插值更能捕捉星期效应。

2.2 关键特征构造:超越原始数据

附件给出的数据字段有限,但我们可以从中挖掘出大量对预测和优化至关重要的特征。

  • 时间特征:这是最基础的。包括年、月、日、星期几、是否周末、是否节假日(需自行根据日历补充)、是否为月初/月末。特别地,对于生鲜商品,节假日前夕通常是采购高峰,需要构造“节假日前第N天”这样的布尔特征。
  • 统计特征:基于历史滑动窗口计算的特征极其有效。例如,过去7天、14天、30天的销量均值、标准差(反映销售稳定性)、最大值、最小值。还可以计算“昨日销量/过去7日均值”这样的比值特征,来捕捉短期波动。
  • 价格相关特征:除了当日的批发价,可以构造“批发价环比变化率”、“当前批发价与过去7天均价的比值”。更重要的是,要尝试构造**“需求价格弹性”的代理特征**。虽然无法直接计算精确的弹性系数,但可以计算历史数据中,价格变化与销量变化的相关性(按周或按月计算),作为一个静态特征输入模型。
  • 损耗与成本特征:单品的损耗率通常与销售时长、商品特性有关。我们可以用“历史平均损耗率”作为一个特征。同时,计算“成本价”,即(批发价 * (1 + 损耗率)),这才是真正的单位商品成本,是利润计算的基础。
  • 品类聚合特征:题目要求中有对总品类的约束。因此,除了单品特征,还需要构造品类层级的特征,如该品类下所有单品当日销量的总和、均值、方差等,这些特征可以帮助模型感知品类整体的销售态势。

注意:特征工程不是越多越好。我们当时先用了一个简单的线性模型(如Lasso回归)跑了一遍特征重要性排序,剔除了大量共线性强或重要性极低的特征,最终保留了大约15-20个核心特征,这大大提升了后续复杂模型的训练效率和稳定性。

3. 销量预测模型的选择与融合实战

预测未来7天每天数百个单品的销量,是一个典型的多变量时间序列预测问题。没有哪个模型是银弹,我们的策略是“分而治之,集成学习”。

3.1 模型选型:为什么是它们?

我们放弃了使用一个巨型模型预测所有单品的想法,因为不同蔬菜的销售模式差异巨大(例如,生姜和大白菜的销售曲线完全不同)。我们为每个单品单独建立预测模型,但共享特征工程框架和模型结构。

  • 基础模型 - LightGBM:梯度提升树模型对于处理表格数据、捕捉非线性关系和特征交互有天然优势。它不需要严格的时间序列结构,可以方便地融入我们构造的丰富特征。我们用它作为基准模型和集成学习的一员。它的预测速度快,能快速给出一个不错的基线。
  • 核心模型 - 时序深度学习模型(如LSTM、TCN、Transformer):为了更好捕捉长期依赖和复杂时序模式,我们使用了深度学习模型。这里有几个关键点:
    • 输入序列构造:我们将数据组织成[样本数, 时间步长, 特征数]的格式。时间步长我们选择了30天(约一个月),用过去30天的特征来预测未来1天的销量。为了预测未来第7天,我们需要递归预测(使用模型预测出的第1天结果作为输入的一部分,来预测第2天,依此类推),或者更优地,采用Seq2Seq架构直接输出未来7天的序列。
    • 损失函数设计:没有使用简单的MSE,而是采用了分位数损失函数(Quantile Loss)。因为补货决策不仅关心预测的平均值,更关心预测的不确定性。我们同时预测了销量的第10、第50(中位数)、第90分位数。中位数用于后续优化,而第10和第90分位数则构成了一个“可能区间”,为制定稳健的补货策略提供了边界参考。
  • 辅助模型 - Prophet:Facebook的Prophet模型在处理具有强季节性和假日效应的商业时间序列上表现稳健。我们用它来捕捉年度、季度、星期季节项。虽然它对于融入我们构造的复杂外部特征(如价格)能力较弱,但其对趋势和季节性的分解结果,可以作为特征加入到LightGBM或LSTM模型中。

3.2 模型融合与不确定性量化

单一模型总有局限。我们采用了加权平均融合的方式。权重不是主观设定的,而是通过一个留出集(比如最后一个月的数据)来优化确定。具体来说,我们用每个模型在留出集上预测未来1-7天的误差(如sMAPE)的倒数作为权重的基准,再进行归一化。

更重要的是不确定性传递。LSTM的分位数预测给出了不确定性区间。在融合时,我们对三个分位数预测分别进行加权平均,最终得到融合后的第10、50、90分位数预测值。这个“预测区间”至关重要。在后续的优化模型中,我们可以设计两套方案:一套基于中位数预测的“乐观”方案,另一套基于第10分位数预测的“保守”方案,以应对可能出现的销售不及预期的情况。

踩坑实录:我们最初直接用LSTM预测未来7天销量,发现对于销售波动大的单品,预测结果在后期(第6、7天)会变得非常不稳定。后来改为“滚动预测”模式:用模型预测明天,将预测结果(连同真实特征)作为已知数据加入历史序列,再预测后天,如此循环7次。虽然这会累积误差,但通过在每个滚动步加入预测置信度作为衰减因子,并融合Prophet的稳定趋势,效果比直接输出7天序列好很多。

4. 定价与补货联合优化模型的构建

这是整个赛题最核心、最体现建模功力的部分。目标函数很明确:最大化未来7天的总利润。利润 = 销售收入 - 成本。销售收入 = 销量 * 零售价;成本 = 补货量 * 批发价 + 损耗成本(损耗量 * 成本价)。

但约束条件非常复杂:

  1. 单品销售总量约束:每个单品未来7天的总销量不能超过该单品过去同期(比如2019-2022年7月1-7日)最大销量的1.1倍。这是一个“天花板”,防止你过度乐观。
  2. 品类销售配额约束:每个蔬菜品类(如叶菜类、茄类)的未来7天总销量,必须控制在该品类总销量的25%-35%之间。这要求你在不同品类间合理分配资源。
  3. 利润率约束:未来7天的整体利润率(总利润 / 总成本)不能低于22%,且不能高于30%。这直接限制了你的定价空间。
  4. 损耗率约束:未来7天的平均损耗率不能超过同期历史平均损耗率的1.1倍。这要求你的补货量必须精准,不能造成大量积压。
  5. 定价与补货逻辑约束:零售价不能低于成本价(否则亏本),补货量要能满足预测销量(考虑损耗),且补货量、销量、损耗量之间要满足期末库存 = 期初库存 + 补货量 - 销量 - 损耗量的动态平衡关系。

4.1 模型抽象:一个带约束的非线性规划问题

我们可以将问题抽象如下:

  • 决策变量:对于每个单品i,每天t,我们需要决定其零售价P_it和补货量Q_it
  • 目标函数:MaximizeΣ_i Σ_t [ D_it(P_it) * P_it - (Q_it * W_it + L_it * C_it) ]。其中D_it(P_it)就是需求函数,表示销量是价格的函数;W_it是批发价;L_it是损耗量;C_it是成本价。
  • 约束条件:即上述5大类约束,其中需求函数D_it(P_it)、损耗量L_it都与决策变量Q_itP_it以及预测的销量基数密切相关。

最大的难点在于需求函数D_it(P_it)是未知的、非线性的。我们无法直接从历史数据中拟合出一个精确的、适用于未来每一天每一个单品的价格-销量函数。

4.2 我们的求解策略:两阶段迭代逼近

我们采用了一种数据驱动的迭代优化方法,避免了直接求解复杂的非线性规划。

第一阶段:需求弹性估计与价格试探我们假设在短期内,需求价格弹性相对稳定。利用历史数据,我们为每个单品估计了一个基准价格弹性系数 ε_i(取对数后的线性回归斜率)。那么,需求函数可以简化为:D_it = D0_it * (P_it / P0_it)^ε_i。其中D0_it是我们预测模型给出的、在基准价格P0_it(例如,历史同期均价或当前批发价加成)下的销量预测值(中位数)。

第二阶段:线性规划近似求解在给定弹性系数 ε_i 和基准预测D0_it后,需求函数D_it(P_it)就确定了。此时,目标函数和约束中关于P_it的部分变成了非线性(幂函数)。为了高效求解,我们在基准价格P0_it附近对需求函数进行一阶泰勒展开(线性化)。 即:D_it ≈ D0_it + ε_i * (D0_it / P0_it) * (P_it - P0_it)。 经过这样的线性化处理,原问题被近似为一个大规模的线性规划(LP)问题。决策变量是每个单品每天的零售价P_it和补货量Q_it。我们可以使用成熟的求解器(如PuLP调用CBC,或直接用SciPy的线性规划库)快速求解。

第三阶段:迭代反馈与调整线性化是在基准点附近进行的,如果求出的最优价格P_it*离基准价格P0_it太远,线性近似的误差会很大。因此,我们引入迭代:

  1. 用求出的P_it*作为新的基准价格P0_it_new
  2. 根据新的价格,利用需求函数公式反推一个新的预期销量D1_it
  3. 将这个新的预期销量D1_it与原始预测D0_it进行比较,如果差异较大,则用D1_it修正我们的销量预期(可以取加权平均),然后回到第二阶段,重新线性化并求解。
  4. 如此迭代2-3次,直到价格和销量的变化小于某个阈值,结果就稳定了。

这个方法的好处是,它将复杂的非线性问题分解为一系列线性规划问题,求解效率高,且能很好地耦合价格与销量的关系。同时,通过迭代保证了解的局部最优性。

核心技巧:约束处理是优化成败的关键。特别是品类销售配额约束(25%-35%),直接硬约束有时会导致无解。我们的处理方法是引入松弛变量,将其转化为软约束,并在目标函数中增加对违反约束的惩罚项。例如,允许品类销量占比略微超出范围,但每超出1%,就在总利润中扣除一个较大的惩罚成本。这样,求解器会努力满足约束,但在实在无法完全满足时,也能给出一个“破坏最小”的可行解,这在实际商业决策中更合理。

5. 结果分析、稳健性检验与报告撰写要点

模型跑出结果只是第一步,如何分析和呈现结果,往往决定了论文的档次。

5.1 结果的可视化与业务解读不要只扔出一堆数字表格。我们做了以下几类图:

  • 单品决策透视:挑选几个有代表性的单品(如高销量、高损耗、高利润的),绘制其未来7天的预测销量曲线、建议补货量曲线、建议零售价曲线,并放在同一张图上,用阴影区表示预测的不确定性区间。旁边附上该单品的关键指标(如历史均价、建议均价比、预期利润率)。一目了然。
  • 品类配额达成情况:绘制柱状图,展示每个品类未来7天的预测销量占比,并用两条红线标出25%和35%的上下限,清晰展示优化结果是否满足约束。
  • 价格-销量散点图:将所有单品未来7天的建议零售价与预测销量画成散点图,可以观察是否存在“高价低量”或“低价高量”的普遍规律,印证需求定律。
  • 利润贡献分析:绘制帕累托图(Pareto Chart),展示哪些单品或品类贡献了主要利润,为商超的重点关注商品提供依据。

5.2 稳健性检验:模型经得起推敲吗?这是拿高分的关键。我们设计了以下检验:

  • 历史回测:将我们的模型应用到2022年7月1-7日(假设我们只有之前的数据),模拟当时的决策,并与实际发生的销售、损耗数据对比。计算模拟利润与实际利润的差距,分析差距来源(是预测不准,还是优化模型对约束太敏感?)。
  • 敏感性分析
    • 参数敏感性:弹性系数 ε_i 估计不准怎么办?我们将所有单品的 ε_i 同时上下浮动10%,重新运行优化模型,观察总利润和关键决策变量(如均价、补货总量)的变化幅度。如果变化不大,说明模型对弹性系数不敏感,结果稳健。
    • 预测不确定性分析:用我们预测的第10分位数(悲观场景)和第90分位数(乐观场景)的销量,分别代入优化模型,得到三套决策方案。对比三套方案下的利润区间和约束满足情况。这能充分展示模型在不同市场环境下的表现,体现决策的鲁棒性。
  • 场景分析
    • 批发价波动场景:假设未来一周某种主要蔬菜的批发价突然上涨20%,我们的模型给出的决策如何调整?调整后的利润变化多少?
    • 突发需求场景:假设因为某个社会事件,某类蔬菜的需求突然增加(在预测销量基础上增加15%),我们的补货和定价策略是否有足够的弹性来应对?

5.3 论文撰写:将思考过程故事化国赛论文评审时间紧,评委喜欢看到清晰的逻辑主线。我们的论文结构大致如下:

  1. 问题重述与分析:不是简单抄题目,而是用自己的话提炼出问题的本质、核心目标和挑战,点明“预测-优化”耦合的关键难点。
  2. 模型准备:详细介绍数据预处理、特征工程、需求弹性估计的方法和理由。这部分体现基本功。
  3. 预测模型:阐述为什么选择多模型融合,如何量化不确定性。用图表展示预测效果(如部分单品的预测 vs 实际对比图)。
  4. 优化模型:这是核心章节。详细阐述如何建立带约束的利润最大化模型,如何线性化处理,以及迭代求解算法。画出算法流程图。
  5. 模型求解与结果:给出关键结果数据,并用丰富的图表进行可视化展示和业务解读。
  6. 模型检验与评价:展示稳健性检验和敏感性分析的结果,证明模型可靠。分析模型的优点。
  7. 模型推广与改进:谦虚地指出模型假设的局限性(如需求函数形式较简单),并提出未来可以引入更复杂的消费者行为模型、竞争对手定价信息等改进方向。

通篇语言要严谨、简洁,避免口语化。图表要精美、信息量大,且都有必要的说明文字。最终,你的论文应该让评委感觉,你不仅给出了答案,更展示了一套解决此类商业决策问题的完整、可靠、可复现的方法论。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询