数学建模竞赛:动态优化与需求预测在库存定价决策中的应用
1. 赛题核心与破题思路:从“蔬菜类商品”到“定价与补货”的建模本质
每年国赛C题,总给人一种“接地气”的感觉,今年也不例外。题目一出来,“蔬菜类商品的自动定价与补货决策”这个标题,让不少同学觉得亲切,毕竟谁没买过菜呢?但恰恰是这种“亲切感”,最容易让人掉以轻心。我见过太多队伍一上来就扎进附件的数据海洋里,开始疯狂清洗、画图,试图从销售数据里直接“看”出规律。这其实就走偏了。
这道题的核心,根本不是让你去做一个“蔬菜销售数据分析报告”,而是让你构建一个能够支撑“自动定价”与“自动补货”决策的数学模型。数据分析只是手段,是为你构建模型服务的。题目附件里给出的销售流水、批发价格、损耗率,都是构建这个模型的“砖瓦”。你需要思考的是:一个超市的运营者,每天面临哪些决策?无非是:进什么货(补货决策)、进多少(补货量)、卖多少钱(定价决策)。而做这些决策的目标是什么?在商业语境下,最核心的目标通常是最大化利润,同时兼顾一些约束,比如尽量减少损耗、保证商品新鲜度(可售时间)、满足市场需求等。
所以,破题的第一步,是把生活化的“卖菜”问题,翻译成数学建模的语言。这本质上是一个动态优化问题,更具体地说,是一个多阶段决策问题。每一天(或每一个销售时段)都是一个决策阶段,你在每个阶段开始时,根据当前库存、历史销售、未来预测等信息,决定今天的补货量和定价策略,然后进入下一个阶段,如此循环。利润是你在所有阶段获得的总收益减去总成本(进货成本、损耗成本、可能的缺货惩罚等)。
理解了这个本质,你就不会被庞杂的数据吓到。你的任务清晰了:建立一个以总利润最大化为目标,以补货量和定价为决策变量,以库存动态、损耗约束、市场需求响应等为约束的优化模型。所有附件数据,都是为了帮你量化模型中的参数,比如需求函数、损耗率函数等。
2. 数据预处理与特征工程:从原始流水到模型“燃料”
拿到附件,尤其是销售流水明细这种“大数据”,第一步不是跑模型,而是静下心来做好数据预处理。这一步做扎实了,后面的建模才能顺风顺水。很多队伍模型想法天花乱坠,但一跑就崩,八成是数据没洗干净。
2.1 销售流水数据的深度清洗与聚合
附件1的销售流水是核心。你需要按单品编码和日期进行聚合,计算出每个单品每天的销量和销售额。这里有几个关键处理点:
- 异常值处理:检查是否有销量为负、销售额为负或极高极低的记录。对于明显的录入错误(如数量为9999),需要根据业务逻辑进行剔除或修正。一个常用方法是使用箱线图(Boxplot)识别离群点,或采用3σ原则(假设数据服从正态分布,剔除均值±3倍标准差以外的数据)。
- 缺失值处理:如果某天某个单品完全没有销售记录,是代表销量为0,还是数据缺失?这需要结合上下文判断。对于生鲜蔬菜,如果当天有进货但无销售记录,很可能是数据缺失;如果当天无进货也无销售,则销量为0的可能性大。可以采用前后日期插值,或标记为0并进入后续分析。
- 数据聚合:聚合后,你得到的是一个“面板数据”,即每个单品在每个日期有一条记录,包含销量、销售额。此时,可以计算一个非常重要的衍生特征:每日平均售价(销售额/销量)。这个价格是市场实际成交价,是你构建需求函数的基础。
2.2 批发价格与损耗率数据的融合
附件2和附件3提供了成本和损耗信息。这里的关键是数据对齐。
- 批发价格:附件2给出了单品在不同日期的批发价格。你需要将其与清洗后的销售数据按单品和日期精确匹配。匹配后,每个单品每天的成本就明确了。这是计算毛利润(销售额 - 成本 * 销量)的基础。
- 损耗率:附件3的损耗率数据通常是按品类给出的。你需要建立“单品编码”到“品类”的映射关系(题目一般会给出或可以从编码中推断),将品类损耗率赋给对应的单品。注意,损耗率是一个比例,它作用于的是当日未售出的库存。因此,你需要先有库存数据(初始库存+补货-销量),才能计算损耗量。
2.3 构建模型所需的时序特征
仅仅有每天的销量和价格是不够的。为了预测需求,你需要构建能够反映时间规律的特征。这属于特征工程,对后续建立预测模型至关重要。
- 时间特征:提取日期中的年、月、日、星期几、是否为周末、是否为节假日(需要外部日历)。蔬菜销售受星期效应和节假日效应影响极大。
- 滞后特征:这是时序预测的核心。创建过去1天、3天、7天(一周)的销量、价格滞后值作为特征。例如,“单品A前一天的销量”很可能对今天的销量有影响。
- 滑动统计特征:计算过去3天、7天的平均销量、销量标准差、价格均值等。这能反映近期趋势和波动。
- 品类交互特征:可以考虑同一品类内其他单品的销量或价格,作为反映品类整体行情的特征。
注意:构建滞后特征会导致数据最初几行出现缺失值(因为前面没有历史数据),需要在模型训练时妥善处理,或直接剔除。
经过以上步骤,你得到的是一个规整的、包含每个单品每日“销量、售价、成本、损耗率、多种时间特征”的数据集。这才是能喂给模型的“燃料”。
3. 需求预测模型搭建:价格与销量关系的量化
定价和补货都依赖于对未来的预测。补货需要预测未来销量,定价需要知道“价格变动会对销量产生多大影响”。因此,建立一个可靠的需求预测模型是承上启下的关键。这里的“需求”,即在给定价格下的预期销量。
3.1 需求函数的形式选择
经济学中,需求通常与价格负相关。常用的需求函数形式有:
- 线性需求函数:
Q = a - b*P。简单直观,但可能无法很好地拟合实际数据中复杂的非线性关系。 - 指数型/对数线性需求函数:
ln(Q) = a - b*P或Q = a * exp(-b*P)。这假设需求的价格弹性是常数,在实际中更为常用。 - 幂函数需求函数:
Q = a * P^(-b)。这也是常数弹性模型,取对数后变为线性:ln(Q) = ln(a) - b*ln(P)。
我个人的经验是,对于国赛这类数据,可以先尝试对数线性模型。因为它将指数增长关系转化为线性关系,便于用线性回归求解,且经济学解释性强(系数b可以近似理解为需求价格弹性)。
3.2 模型的具体实现与求解
以对数线性模型ln(Q) = β0 + β1*P + β2*X1 + ... + βn*Xn + ε为例。
Q:销量(因变量)。P:价格(核心自变量)。X1...Xn:其他控制变量,即我们前面构建的时间特征、滞后特征等(如星期几、节假日、历史平均销量等)。ε:随机误差项。
操作步骤:
- 数据准备:对销量
Q取自然对数,作为新的因变量ln_Q。确保数据中没有零销量,否则取对数会报错(可以考虑将0替换为一个极小值,或使用ln(Q+1),但需要解释)。 - 模型训练:使用线性回归(如最小二乘法)对每个单品(或每个品类)分别进行拟合。为什么要分单品?因为不同蔬菜的需求特性(价格弹性、季节性)差异巨大。将全部数据混在一起训练一个模型,效果通常很差。
- 参数解读:拟合后得到系数
β1。由于模型是ln(Q) = ... + β1*P + ...,因此需求的价格弹性近似为-β1 * P_mean(其中P_mean是训练数据中的平均价格)。弹性为负,表示价格上升,需求下降。 - 模型验证:必须使用时间序列交叉验证。例如,用前80%的数据训练,预测后20%的数据,计算RMSE(均方根误差)、MAE(平均绝对误差)等指标。严禁随机划分训练测试集,这会严重高估模型性能,因为时序数据具有自相关性。
3.3 引入竞争因素与外部变量
题目可能暗示或数据可能显示,单品之间存在替代或互补关系。例如,菠菜价格涨了,消费者可能转而购买油菜。你可以在需求函数中引入相关商品的价格作为自变量。此外,如果数据允许,还可以考虑天气、温度等外部因素,这些对蔬菜需求影响显著。
4. 库存动态与损耗建模:补货决策的约束核心
补货决策不仅取决于预测的需求,更受制于库存的动态变化和由此产生的损耗。这是本题区别于普通预测题的关键,也是建模的难点和亮点。
4.1 库存状态转移方程
这是描述库存如何随时间变化的核心方程。假设我们以“天”为决策周期:
I_{t+1} = I_t + O_t - D_t - L_t
其中:
I_t:第t天开始时的库存量。O_t:第t天早晨的补货到货量(决策变量之一)。D_t:第t天的实际需求量(由需求函数和定价决策共同决定,是一个随机变量,但我们用预测值d_t作为其期望)。L_t:第t天发生的损耗量。
4.2 损耗量L_t的计算模型
损耗是生鲜商品的核心成本。题目给出了损耗率,但损耗率作用于哪些库存?常见且合理的建模方式是:
L_t = θ * (I_t + O_t - D_t)^+
解释:(x)^+表示max(x, 0)。即,损耗发生在当天未售出的库存上。θ是损耗率(来自附件3)。这个模型意味着,如果你当天全部卖光,损耗为零;如果没卖完,剩余库存就会按比例损耗。
更精细的模型可以考虑损耗与库存时间的关系,例如采用两阶段或多阶段损耗模型:新鲜度高的第一天损耗率低,第二天损耗率升高。但这需要更复杂的假设和数据支持,国赛中采用上述单阶段模型通常即可。
4.3 库存成本与缺货成本
在优化目标(利润)中,除了进货成本和销售收入,还需要考虑:
- 库存持有成本:资金占用、仓储管理等。可以简化为一个比例
h,成本为h * I_t。 - 缺货成本:因缺货导致的销售损失和商誉损失。当需求
D_t大于可用库存(I_t + O_t)时,发生缺货。缺货量S_t = max(D_t - (I_t + O_t), 0)。缺货成本可以是单位缺货惩罚p_s,成本为p_s * S_t。
将损耗、库存持有成本和缺货成本纳入目标函数,你的模型才是一个完整的商业决策模型。
5. 整合优化模型构建与求解策略
现在,我们将前四部分的模块整合起来,形成一个完整的数学优化模型。
5.1 模型定义(以确定性模型为例)
假设我们规划未来T天(如一周)的决策,并假设需求预测是确定的(即D_t= 预测值d_t)。这是一个简化,但可以先搭建框架。
决策变量:
O_t:第t天的补货量(非负)。P_t:第t天的销售定价(大于成本)。
目标函数(最大化总利润):
Maximize Σ_{t=1}^{T} [ P_t * min(d_t, I_t+O_t) - c_t * O_t - h * I_t - p_s * S_t ]其中:
P_t * min(d_t, I_t+O_t)是第t天的实际销售收入(销量不能超过可用库存)。c_t是第t天的单位进货成本(来自附件2)。h * I_t是库存持有成本。p_s * S_t是缺货成本,S_t = max(d_t - (I_t+O_t), 0)。- 注意,损耗成本已经体现在
I_t的动态变化中,因为它减少了可用于第二天销售的库存。
约束条件:
- 库存动态:
I_{t+1} = (1-θ) * (I_t + O_t - min(d_t, I_t+O_t))。这里min(d_t, I_t+O_t)是实际销量,(I_t + O_t - 实际销量)是未售出库存,乘以(1-θ)得到扣除损耗后的次日库存。 - 需求函数:
d_t = f(P_t, X_t),即第t天的预测需求量是价格P_t和其他特征X_t的函数(来自第三部分的模型)。 - 非负与逻辑约束:
O_t >= 0,P_t >= c_t(价格不低于成本),I_t >= 0。 - 容量约束(可选):总库存
I_t可能有一个上限(仓库容量)。
5.2 求解策略与算法选择
上述模型是一个带约束的非线性规划问题,因为目标函数和需求函数f(P_t)通常是非线性的。直接求解析解非常困难,必须采用数值求解方法。
- 离散化搜索法(推荐给编程基础一般的队伍):将价格
P_t在合理区间内离散化为多个水平(如从成本价到2倍成本价,取10个点)。对于每个给定的价格序列,需求d_t就确定了,此时模型退化为一个以O_t为决策变量的线性规划或动态规划问题,很容易求解(可用MATLAB的linprog或Python的PuLP、scipy.optimize.linprog)。然后遍历所有价格组合,选择总利润最大的那一组。虽然计算量随天数和价格离散化点数指数增长,但对于T较小(如7天)的情况,在可接受时间内可以完成。这是国赛中非常实用且易实现的策略。 - 智能优化算法:将
O_t和P_t同时作为决策变量,使用遗传算法(GA)、粒子群算法(PSO)等直接优化总利润。这类算法能处理非线性,但调参复杂,且容易陷入局部最优,结果稳定性需要多次运行验证。 - 随机规划或鲁棒优化(进阶):如果考虑需求的不确定性(更符合现实),可以将
D_t视为随机变量,目标函数变为最大化期望利润。这需要知道需求的概率分布,求解难度更大,但模型更高级。
5.3 模型输出与决策支持
求解模型后,你会得到未来T天每个单品的最优补货量序列{O_1, O_2, ..., O_T}和最优定价序列{P_1, P_2, ..., P_T}。这就是“自动定价与补货决策系统”的输出。
在实际撰写论文时,你需要展示关键单品的决策结果,并用清晰的图表展示补货和价格随时间的变化趋势,并结合需求预测和库存曲线解释其合理性。例如:“由于预测周末需求上涨,模型建议在周五增加补货;同时,为了在保质期结束前清空库存,模型对临近损耗的菜品进行了降价促销。”
6. 灵敏度分析与模型评价:让模型结论更可信
模型建完了,结果出来了,但评委一定会问:你的模型可靠吗?参数变一变,结果会不会大变?这就需要灵敏度分析和模型评价。
6.1 关键参数灵敏度分析
选择几个对模型结果影响最大的参数,在其合理范围内变动,观察目标函数(总利润)和核心决策变量的变化程度。
- 需求价格弹性:这是最重要的参数。在你的需求函数中,弹性系数增加10%(消费者对价格更敏感),总利润和最优价格会如何变化?通常,弹性越大,最优定价会越低,利润也可能下降。
- 损耗率
θ:将损耗率上下浮动20%,观察补货策略的变化。损耗率升高,模型会倾向于更频繁、更小批量的补货(Just-in-Time),以避免库存积压导致损耗。 - 缺货成本
p_s:提高缺货成本,模型会倾向于持有更多安全库存,补货量会更积极。
分析时,可以制作像下面这样的表格,清晰展示变化趋势:
| 参数变动 | 总利润变化趋势 | 平均补货量变化趋势 | 平均定价变化趋势 | 原因分析 |
|---|---|---|---|---|
| 需求弹性增加10% | 下降 | 基本不变或略降 | 下降 | 价格敏感性增强,提价空间缩小,需降价促销量以维持收入。 |
| 损耗率增加20% | 显著下降 | 下降,频次可能增加 | 可能降低(促销清库存) | 库存持有风险加大,倾向于减少单次补货量,加快周转。 |
| 缺货成本增加50% | 下降(因成本项增加) | 增加 | 可能微增以弥补成本 | 为避免缺货,增加安全库存,导致库存成本上升。 |
6.2 与基准策略对比
为了体现你模型的优越性,必须设计一个或多个基准策略进行对比。常见的基准策略有:
- 经验策略:每天补货量为前一天销量,价格固定为成本加成一定比例(如20%)。这是最简单的“跟风”策略。
- (s, S)策略:当库存低于s时,补货至S。这是一个经典的库存管理策略,你需要为你的模型数据拟合出最优的s和S。
- 仅预测不优化:用你的需求预测模型预测明天销量,然后按预测销量补货,价格固定。
将你的优化模型的结果与这些基准策略在同一组测试数据上进行模拟,比较总利润、平均损耗率、缺货率等关键绩效指标(KPI)。用柱状图或折线图直观展示你的模型能提升多少利润,降低多少损耗。
6.3 模型优缺点与推广
客观地讨论你模型的优点(如综合考虑定价与补货联动、引入损耗动态、实用性强等)和局限性(如假设需求预测完全准确、未考虑突发天气或竞争、参数依赖历史数据等)。并提出可能的改进方向,例如引入随机需求、建立多品类联合优化模型、结合机器学习提升预测精度等。最后,简要说明模型可以推广到其他生鲜零售、时尚快消等具有类似“时效性强、需求波动大、存在损耗”特征的行业。
整个建模过程,从数据清洗到模型评价,是一个逻辑严密的闭环。国赛评审看重的是问题分析的深度、模型建立的合理性、求解过程的严谨性以及结果分析的洞察力。把每个环节的“为什么”想清楚、讲明白,比堆砌复杂的算法更重要。