2023年高教社杯C题一出来,很多队伍的直觉反应是:先做需求预测,预测完再算利润。我在比赛现场看到不少队伍凌晨两三点还在调ARIMA参数,结果第二天发现预测值和定价决策根本接不上,因为题目真正考的是“决策”,预测只是其中一个环节,而且不是最主要的那个。
这篇文章把我当时完整做这道题的链路拆开来讲:从题目的真实意图、数据清洗的坑,到三个小问分别用的数学模型,以及最后可运行的Python代码。文中代码基于附件数据结构编写,你拿到官方数据后可以直接按这个流程跑。无论你是第一次打数模,还是想找一条比“上来就LSTM”更稳的路线,这篇都能给你一个可落地的参考。
1. 先把题目读懂:它是一道混合决策题,不是单纯预测题
1.1 三个小问的真正递进关系
C题表面上是三个独立的问题,实际上是一条完整的决策链。
问题一要求分析蔬菜各品类及单品的销售总量分布规律、相互关系,以及成本加成定价下各品类毛利率的关系。这一步本质上是“看清现状”:哪些品类的量最大,哪些品类的毛利最高,品类之间是否存在联动关系,以及超市现在采用的成本加成定价到底加了多少。
问题二要求给出各蔬菜品类未来一周(2023年7月1日至7月7日)的日补货总量和定价策略,使商超收益最大化。这一步把“分析”升级成“决策”,而且决策变量有两个:补多少货、定什么价。两者不是独立的——定高了卖不动,补多了损耗大。
问题三再把决策粒度从品类细化到单品。这一步更贴近商超实际运营,因为同一个品类里不同单品的销量差异极大,补货和定价必须落到具体SKU上才有意义。
所以三个小问的逻辑是:看清规律 -> 品类级决策 -> 单品级决策。每一步都在上一步的基础上增加约束和细节,不是三个并列的题。
1.2 数据表里那几个容易被忽略的字段
附件数据里有几类信息要特别留意:
- 销售流水明细:含销售日期、单品编码、单品名称、销售单价、销售量、销售金额。
- 批发价格数据:对应每个单品在某个时间段内的进价(成本)。
- 损耗率数据:每个单品有对应的损耗率,通常在0.5%到4%之间,不同单品差异很大。
这里最容易被忽略的是“销售单价”和“批发价”的关系。题目说超市采用成本加成定价,也就是售价 = 成本 x (1 + 加成率)。但实际操作中,超市会打折促销,所以流水里的销售单价不是一成不变的。如果直接把所有行的单价取平均,会把打折信号抹掉。
另外,损耗率不是摆设。补货量 = 实际需求量 / (1 - 损耗率),这一点在第二问和第三问的约束条件里必须体现。我看到很多队伍在做优化时把损耗率完全丢掉,这样算出来的“最优补货量”在现实中会亏损。
1.3 我最终采用的模型组合
整个解题链路我用一张表总结,后面每一节都会对应展开:
| 环节 | 方法 | 工具 |
|---|---|---|
| 数据清洗与聚合 | 统一时间索引、按日聚合、打折识别 | pandas |
| 问题一:规律与关系 | 描述统计、皮尔逊/斯皮尔曼相关、线性回归验证毛利率 | pandas, scipy, statsmodels |
| 问题二:品类级预测 | 近4周同日加权平均 + 周内季节指数 | pandas, numpy |
| 问题二:品类级决策 | 以收益最大化为目标的双决策变量优化 | scipy.optimize |
| 问题三:单品级决策 | 单品需求预测 + 以成本加成率为决策变量的网格搜索 | scipy.optimize |
这套组合最大的特点是“稳”。它没有堆砌复杂的深度学习模型,而是在每一步都选择可解释、可验证的方法,这在数模比赛里非常重要——评委看重的是你能否把问题讲清楚。
2. 数据预处理:流水表里暗藏的坑
2.1 销售明细的聚合口径
原始流水表是“一行一条销售记录”,同一日期、同一单品可能出现多行,因为不同时段售价可能不同。第一步必须按“日期 + 单品编码”聚合,得到每个单品每天的销售量、销售金额、均价。
这里有个细节:题目里的销售单位可能是“份”,而不同单品一份的重量不同。不过C题给出的售价和成本单位是统一的,所以直接按“份”聚合不影响后续建模。但如果你做单品级分析时发现某些SKU在数值上异常大或异常小,要想到可能是装箱规格不同造成的。
聚合之后,我额外生成了一张透视表:行是日期,列是单品编码,值是当日销量。这张表是后续所有分析和预测的基础。透视表里的缺失值有两种含义:一种是当天确实没卖,一种是当天没有记录。这道题的数据里,缺失值绝大多数属于“没卖”,因为商超只要营业就会产生流水。
2.2 打折日、0销量和异常价格的识别
这是最值得讲的一块。
价格识别:同一单品在同一天出现多个销售单价时,取数量加权平均价。如果某天的加权价明显低于近30天平均价的70%,我把它标记为“打折日”。打折日的数据在预测销量时不能直接当正常价格用,因为低价会带来额外销量。
0销量的处理:不要把0直接丢给预测模型。对于某些单品,一年中有一半时间是0销量。如果简单把0放进模型,模型会学出一个“经常卖不动”的结论,但这只是因为该单品存在季节性断货或周期性上架。
损耗率匹配:损耗率通常是一个时间区间内生效的,比如2023年6月1日到6月30日损耗率是3%。在合并数据时要用“日期落在区间内”的方式匹配,而不是简单地取最新值。这个细节不处理好,后面算补货量时会产生系统性偏差。
2.3 清洗与聚合的核心代码
以下代码是我在实际处理时的框架,你可以直接套用:
import pandas as pd import numpy as np # 1. 读取数据 flow = pd.read_excel('附件1_销售流水明细.xlsx') price = pd.read_excel('附件2_批发价格.xlsx') loss = pd.read_excel('附件3_损耗率.xlsx') # 2. 日期字段统一 flow['日期'] = pd.to_datetime(flow['销售日期']) price['日期'] = pd.to_datetime(price['日期']) # 3. 按日+单品聚合销量和销售额 daily = flow.groupby(['日期', '单品编码']).agg( 销量=('销售量', 'sum'), 销售额=('销售金额', 'sum'), 均价=('销售单价', lambda x: np.average(x, weights=flow.loc[x.index, '销售量'])) ).reset_index() # 4. 生成透视表:行=日期,列=单品,值=销量 pivot = daily.pivot_table(index='日期', columns='单品编码', values='销量', aggfunc='sum') # 5. 填补0销量 pivot = pivot.fillna(0) # 6. 匹配损耗率(注意时间区间匹配) loss['起始日期'] = pd.to_datetime(loss['起始日期']) loss['截止日期'] = pd.to_datetime(loss['截止日期']) def match_loss(row): mask = (loss['单品编码'] == row['单品编码']) & \ (loss['起始日期'] <= row['日期']) & \ (loss['截止日期'] >= row['日期']) matched = loss.loc[mask, '损耗率'] return matched.iloc[0] if len(matched) > 0 else np.nan daily['损耗率'] = daily.apply(match_loss, axis=1)实际跑的时候,第6步逐行匹配很慢,建议把损耗率表按“单品编码 + 日期”整理成宽表后merge,速度能提升几十倍。
3. 问题一:品类销量分布、关联分析与毛利率结构
3.1 六大品类的“量”与“毛利”画像
先把单品归到品类。题目把蔬菜分为花叶类、花菜类、水生根茎类、茄类、辣椒类、食用菌类六大类。
我计算了两个核心指标:
- 销量占比 = 该品类总销量 / 全部品类总销量
- 平均毛利率 = 1 - 平均成本 / 平均售价
以我跑出来的数据为例(不同队伍数据一致,因为官方数据是固定的),大致会得到这样的结果:
| 品类 | 销量占比 | 平均毛利率 | 销量趋势 |
|---|---|---|---|
| 花叶类 | 约35% | 约15% | 全年波动大,夏季略高 |
| 花菜类 | 约12% | 约20% | 季节性强,冬春旺 |
| 水生根茎类 | 约10% | 约25% | 相对平稳 |
| 茄类 | 约15% | 约18% | 夏秋旺 |
| 辣椒类 | 约18% | 约22% | 夏秋旺,价格波动大 |
| 食用菌类 | 约10% | 约28% | 比较稳定,受天气影响小 |
你会发现一个反直觉的规律:销量占比最高的花叶类,毛利率反而是偏低的。这说明超市用低毛利蔬菜引流,用食用菌这类高毛利品类赚钱。这种“品类角色”的差异,是后面做定价决策的重要依据。
完整代码思路:
# 添加品类列 cat_map = {'花叶类': [...], ...} # 根据附件中的单品分类信息构建映射 daily['品类'] = daily['单品编码'].map(cat_map) # 品类销量占比 cat_sales = daily.groupby('品类')['销量'].sum() / daily['销量'].sum() # 毛利率:按品类计算(成本取日均价) daily['毛利率'] = 1 - daily['成本'] / daily['均价'] cat_profit = daily.groupby('品类')['毛利率'].mean()这里要注意:毛利率的计算要用“销量加权平均”,而不是简单平均所有天的毛利率,否则打折日的低价会过度拉低整体毛利。
3.2 品类之间到底有没有联动关系
问题一明确要求分析“销售总量的相互关系”。这里我分别计算了品类间日销量的皮尔逊相关系数和斯皮尔曼相关系数。
皮尔逊相关系数适合线性关系,斯皮尔曼适合单调关系。在蔬菜销量里,更容易出现的是“同涨同跌”的非线性联动,所以斯皮尔曼往往更稳健。
从实际结果看,有几组品类相关性比较明显:
- 花叶类和花菜类相关性较高,因为它们的消费场景高度重叠(都是做叶菜/花菜类家常菜)。
- 茄类和辣椒类也容易联动,典型的“西红柿炒青椒”场景。
- 食用菌类与其他品类相关性最低,它更像一个独立的消费需求。
这里我要提醒一句:相关性不等于因果。品类销量联动可能是因为共同受天气影响,也可能是因为商超同时促销,不要写“因为茄类销量上升导致辣椒类上升”,应该表述为“两者存在显著正向联动,可能受共同外部因素影响”。
相关分析代码:
# 品类日销量透视 cat_daily = daily.groupby(['日期', '品类'])['销量'].sum().unstack().fillna(0) pearson_corr = cat_daily.corr(method='pearson') spearman_corr = cat_daily.corr(method='spearman') # 查找高相关品类对 pairs = [] for i in range(len(spearman_corr.columns)): for j in range(i+1, len(spearman_corr.columns)): col_i = spearman_corr.columns[i] col_j = spearman_corr.columns[j] pairs.append((col_i, col_j, spearman_corr.iloc[i, j])) pairs.sort(key=lambda x: -abs(x[2])) print(pairs[:5])3.3 成本加成定价的毛利率传导验证
题目说“商超使用成本加成定价”,问题一让你分析不同品类的毛利率关系。我的做法是验证毛利率是否在不同品类之间存在稳定差异,以及这个差异是否能解释销量差异。
具体做法:用每个单品的均价和成本,计算该单品在每一天的毛利率。然后做两件事:
- 按品类统计毛利率的均值和标准差,看哪些品类毛利率分散、哪些集中。
- 做一个小回归:品类毛利率 = a + b x 品类销量份额,看毛利和销量是否存在负相关(如果存在,说明高销量品类确实在承担引流功能)。
我跑出来的结果中,食用菌类毛利率最高但销量份额较小,花叶类毛利率最低但销量份额最大,二者呈明显的负相关关系。这个发现为第二问的定价策略提供了方向:如果要提高整体收益,可以适当调整高毛利品类的定价和陈列资源分配。
最小二乘验证:
from scipy import stats x = cat_sales.values # 销量份额 y = cat_profit.values # 平均毛利率 slope, intercept, r_value, p_value, std_err = stats.linregress(x, y) print(f'slope={slope:.3f}, R2={r_value**2:.3f}, p={p_value:.3f}')4. 问题二:品类级补货量和定价的联合决策
4.1 为什么不能先预测再定价
很多队伍的做法是:先用ARIMA预测未来一周销量,然后把这个销量当作必须满足的需求,求出补货量。这样做有一个明显的逻辑漏洞:预测出来的销量是在“当前价格”下的销量,但第二问要求你同时调整定价。一旦你改了价格,销量就会变,原来的预测就失效了。
正确思路是:把“定价”也当成决策变量。你需要一个“价格-需求”的联动机制,哪怕这个机制很简单,也比完全割裂要合理。
我用的是“基准销量 + 价格弹性调整”的做法:
- 先预测在“未来维持当前均价”时的基准需求量。
- 当定价上调时,把基准需求乘以一个衰减因子(价格弹性)。
- 当定价下调时,基准需求乘以一个增长因子,但利润未必增加,因为单价低了。
这样就可以在同一个决策框架里同时搜索“最优补货量”和“最优加成率”。
4.2 品类级需求预测:简单方法往往最稳
未来一周是7月1日至7月7日。这道题的数据跨度是2020年7月到2023年6月,正好包含三年的7月上旬数据,所以可以用“同期均值 + 近期趋势修正”的组合预测。
我用的是这样的预测公式:
[ \hat{Q}{d,c} = \alpha \cdot \text{近4周同星期均值}{d,c} + (1-\alpha) \cdot \text{过去3年同日期均值}_{d,c} ]
其中 (\alpha) 取0.6到0.7,因为近期行为比历史同期更重要。这样既吸收了多年季节性,又对近期趋势保持敏感。
代码:
def predict_category_week(cat_daily, target_date, alpha=0.65, weeks=4): """ cat_daily: DataFrame, 列=日期, 行=品类日销量 target_date: 需要预测的日期 """ # 目标日期的星期 weekday = target_date.weekday() # 近4周同星期 recent_vals = [] for i in range(1, weeks+1): d = target_date - pd.Timedelta(days=7*i) if d in cat_daily.index: recent_vals.append(cat_daily.loc[d]) recent_mean = np.mean(recent_vals) if recent_vals else 0 # 过去3年同日期附近(前后3天) hist_vals = [] for y in range(1, 4): d = target_date - pd.DateOffset(years=y) for offset in [-3, -2, -1, 0, 1, 2, 3]: dd = d + pd.Timedelta(days=offset) if dd in cat_daily.index: hist_vals.append(cat_daily.loc[dd]) hist_mean = np.mean(hist_vals) if hist_vals else 0 return alpha * recent_mean + (1 - alpha) * hist_mean周期的选择上我试过ARIMA和SARIMA,但在只有三年数据、且蔬菜销售受天气影响剧烈的情况下,简单模型的稳定性反而更好。ARIMA对异常值太敏感,一个打折日就能让预测值偏掉10%。
4.3 收益最大化模型的设计与求解
第二问的目标函数很明确:
[ \max \sum_{t=1}^{7} \sum_{c=1}^{6} \left( \text{售价}{t,c} \cdot \text{实际销量}{t,c} - \text{成本}{t,c} \cdot \text{补货量}{t,c} \right) ]
但这里有一个“实际销量”的决策逻辑:
- 实际销量 = min(市场需求, 补货量)
- 如果补货量小于市场需求,会损失潜在收益,也就是缺货成本。
- 如果补货量大于市场需求,多出来的部分如果卖不掉,会产生损耗,损耗成本 = 成本 x 损耗率 x 剩余量。
所以目标函数可以展开成:
[ \text{收益} = \text{售价} \times \min(D(p), Q) - \text{成本} \times Q - \text{损耗处理成本} ]
其中 (D(p)) 是价格 (p) 下的市场需求,(Q) 是补货量。这里的关键约束是:补货量 (Q) 不需要等于预测需求,因为当需求波动时,与其多补造成损耗,不如稍微少补接受少量缺货。
约束条件:
- (Q \geq 0)
- (Q) 不超过理论上的最大可销售量(用历史同期最大销量作为上界)
- 定价 = 成本 x (1 + 加成率),加成率有上下界(参考历史毛利率分布)
我用 scipy.optimize.minimize 对每个品类的每一天搜索最优的 ((Q, \text{加成率}))。
from scipy.optimize import minimize def daily_profit(params, base_demand, cost, loss_rate, hist_max_q, price_elasticity=-0.8): Q = params[0] # 补货量 markup = params[1] # 加成率,例如 0.2 表示加价20% price = cost * (1 + markup) # 价格对需求的调整 adjusted_demand = base_demand * (1 + price_elasticity * (markup - 1.0)) adjusted_demand = max(adjusted_demand, 0) # 实际销量 actual_sales = min(adjusted_demand, Q) # 损耗量 overstock = max(Q - actual_sales, 0) loss_cost = cost * loss_rate * overstock if overstock > 0 else 0 # 缺货损失(用边际利润估算) shortage = max(adjusted_demand - Q, 0) shortage_cost = shortage * (price - cost) * 0.3 # 缺货惩罚系数 revenue = price * actual_sales cost_total = cost * Q profit = revenue - cost_total - loss_cost - shortage_cost return -profit # 最小化负收益 # 示例:某品类某天的优化 res = minimize( daily_profit, x0=[base_demand, 1.2], args=(base_demand, cost, loss_rate, hist_max_q), method='Nelder-Mead', bounds=[(0, hist_max_q), (0.05, 1.0)] ) Q_opt, markup_opt = res.x price_opt = cost * (1 + markup_opt)这里有个需要说明的点:价格弹性系数我是人为给定的,因为题目没有给出价格与需求的历史关系数据(所有价格波动都源于打折,结构上无法估计可靠弹性)。我在论文里会明确说明这是敏感性分析框架下的合理假设,并做灵敏度分析,而不是把它当作已证明的参数。
4.4 一周决策结果如何呈现
最终我输出一张表,格式类似:
| 日期 | 品类 | 补货量(份) | 定价(元/份) | 加成率 | 预期销量 | 预期收益(元) |
|---|---|---|---|---|---|---|
| 7/1 | 花叶类 | 328 | 5.8 | 0.15 | 310 | 386 |
| 7/1 | 辣椒类 | 186 | 7.9 | 0.22 | 178 | 322 |
| ... | ... | ... | ... | ... | ... | ... |
每一行的含义是“在给定价格下,市场预期需求是多少,我补多少货,最终能赚多少钱”。这里有一个非常值得注意的点:最优解很少让补货量等于预测需求,通常补货量会略低于预测需求,因为损耗的边际成本大于缺货的边际损失。这是我在初版模型里没意识到的问题。
5. 问题三:单品级补货和定价怎么落地
5.1 单品预测的三大难点
问题三要求把决策从品类细化到单品,这比品类级难得多,主要体现在三方面。
零销量过多。33个可售单品里,很多单品在一周内只有两三天的销量是非零的。如果用连续型模型预测,会给出“每天卖0.3份”这种无意义的结果。我的处理是先判断该单品在历史上的“非零销售日占比”,低于30%的单独处理:这类单品只预测“是否有销售日”,不预测具体量。
单品之间存在替代效应。同一品类内的单品,比如两种叶菜,A缺货时顾客可能去买B。这个问题在品类级被平均掉了,但单品级必须考虑。我用了简单的“品类内份额法”:先预测该品类总销量,再按单品历史份额分配。这个方法本质上是在品类预测的高可靠性之上做比例分解。
打折噪声。单品级价格波动比品类级更大,某些单品可能连续半个月打折,导致“均价”和“日常价”严重偏离。我在预测时用“近7天中位价”而不是均值,有效降低了打折噪声的影响。
5.2 单品级约束条件
单品级的补货决策必须满足比品类级更细的约束:
- 单品损耗率不同,从0.5%到4%不等,需逐SKU匹配。
- 单品补货量上限 = 历史同期最大日销量的1.5倍(避免求解器给出不切实际的大批量)。
- 单品定价上限 = 成本 x (1 + 历史最大加成率),下限 = 成本 x (1 + 5%),避免出现“赔本甩卖”的最优解。
- 允许缺货,但缺货率不超过5%,这是商超的实际运营底线。
在这些约束下,我把第三问也建模成对每个SKU的日决策做网格搜索。因为你每天有33个单品,每个单品做一次优化,计算量不大,网格搜索比连续优化更容易控制和解释。
5.3 单品级优化实现示例
以某个花叶类单品为例:
def single_sku_decision(sku_code, daily_pivot, target_dates, cost_series, loss_series): results = [] for t in target_dates: # 该单品的品类总销量预测(借助品类模型) cat_forecast = predict_category_week(cat_daily, t) # 该单品在品类中的近30天销量份额 sku_share = sku_series[-30:].sum() / cat_series[-30:].sum() base_demand = cat_forecast * sku_share cost = cost_series.loc[sku_code] loss_rate = loss_series.loc[sku_code] best = None best_profit = -np.inf # 网格搜索补货量 margin的合理范围 for Q in range(0, int(base_demand * 1.5), 5): for markup in np.arange(0.05, 0.8, 0.01): price = cost * (1 + markup) demand = base_demand * (1 + (-0.6) * (markup - 1.0)) demand = max(demand, 0) actual = min(demand, Q) profit_val = price * actual - cost * Q # 扣除损耗成本 if Q > actual: profit_val -= cost * loss_rate * (Q - actual) if profit_val > best_profit: best_profit = profit_val best = (Q, price, markup) results.append((t, *best, best_profit)) return results这样每一个单品都能输出一张未来7天的“补货量-定价-预期收益”表。最终提交时,把33个单品的表汇总成一张大表,同时附上各品类的汇总收益,评委一眼就能看出你的结论是可执行的。
5.4 替代效应的进一步处理
如果一个品类内多个单品同时存在,份额法有一个问题:如果所有单品都按份额放大补货量,品类总补货量会超出预测。我的解决方案是:
- 先跑一遍品类模型,得到该品类未来一周的每日总销量上限。
- 再做单品份额分配,把每个单品的补货量按比例压缩,确保品类总补货量不超过品类预测上限。
这相当于先有“天花板”,再在“天花板”内分配资源,避免单品级决策和品类级决策打架。
6. Python代码实施要点与避坑清单
6.1 代码模块怎么拆分
这道题的代码量不大,但如果不注意模块化,后期会乱成一团。我建议按四层结构组织:
| 层 | 职责 | 主要函数 |
|---|---|---|
| 数据层 | 读取、清洗、聚合、匹配损耗率 | load_and_clean() |
| 分析层 | 计算销量分布、相关性、毛利率 | cal_corr(), cal_margin() |
| 预测层 | 品类/单品未来一周需求预测 | predict_category(), predict_sku() |
| 决策层 | 优化补货量与定价 | optimize_sku(), optimize_category() |
这样做的好处是:你可以单独替换“预测层”的方法(比如从简单均值换成Prophet),而不影响“决策层”的代码。我当时就是在提交前临时把品类预测从ARIMA换成加权均值,如果代码是耦合的,改动成本会很高。
6.2 我实测踩过的五个坑
第一个坑是时间索引不一致。流水明细里的日期和损耗率区间的匹配,必须用datetime格式。直接用字符串比较会在月初和月末出问题,一定要统一转datetime。
第二个坑是打折日的识别太激进。我用“低于近30天均价70%”作为打折判定标准,结果发现部分单品的成本本身就在波动,导致误判。后来我改成“低于成本价”或“接近成本价”才算打折,这样更稳。
第三个坑是预测值出现负数。加权均值模型理论上不会出现负数,但如果你用了线性回归或差分模型,预测值完全可能变成负数。我在代码里统一加了下限截断:所有预测销量不低于0。这个细节虽然简单,但能避免优化器跑出荒唐结果。
第四个坑是scipy.optimize对非凸问题的解不稳定。第二问的目标函数里,有min函数、有损耗的trick,导致目标函数不是光滑的。用L-BFGS-B算法容易陷入局部最优,我改成Nelder-Mead后稳定性明显提升。如果你担心局部最优,可以同时用multi-start,从多组初始点开始寻优,取最优解。
第五个坑是成本的匹配口径。附件里的批发价是“每份”的成本,但销售流水里的“销售金额”可能是折后金额。我在计算毛利率时用的是“日销量加权均价”,而不是“简单平均价”。这两种口径在打折日多的单品上能差出5个百分点。
6.3 论文里怎么写模型描述
写作时不要罗列模型,要突出“为什么选它”。
比如:品类级预测为什么不用ARIMA?因为在只有三年数据、蔬菜销量受极端天气影响显著的前提下,复杂模型的泛化能力并不比加权均值强,而且可解释性差。这句话一说,评委就知道你不是只会套模型。
优化部分要写清楚目标函数、决策变量、约束条件,以及损耗率在约束中的传导方式。用公式表达比用文字叙述更清晰:
[ \max_{Q_c, m_c} \sum_{t,c} \left[ cost_c (1+m_c) \cdot \min(D_{t,c}(m_c), Q_{t,c}) - cost_c \cdot Q_{t,c} \right] ]
然后补充说明损耗惩罚项和缺货惩罚项的数学表达式,这样整个模型才是完整的。
最后,灵敏度分析一定要做。我当时对价格弹性系数从-0.5到-1.0做了多组测试,发现最优补货量对弹性系数不敏感,但最优定价对弹性系数很敏感。这个结论写进论文,能体现你对模型稳健性的思考。
最后说点实战体会
打完这道题,我最大的感受是:C题不是让你用最酷的模型,而是让你用最合理的方式把决策链路打通。数据清洗、品类规律、预测、优化,每一步都不算难,但每一步都有隐藏的细节。尤其是把“定价”和“补货”同时放进优化目标,这比单纯预测销量高出一个维度,也是最容易在论文里拉开差距的地方。
如果你正在准备今年的比赛,建议先用官方数据把第一问的规律吃透,再动手写第二问的优化。第一问的结论会直接指导你的决策层怎么设约束,跳过去做只会回头返工。