
1. 赛题核心与破题思路从“蔬菜类商品”到“定价与补货”的系统性拆解拿到2023年国赛C题“蔬菜类商品的自动定价与补货决策”时很多队伍第一反应是去找价格预测模型或者库存优化算法。这没错但容易陷入“只见树木不见森林”的困境。这道题的精髓在于它本质上是一个多目标、多约束、数据驱动的商业决策优化问题而非单纯的预测或优化。题目给出了三个附件附件1是6个单品在2023年7月1日至2023年7月30日的销售流水明细附件2是这6个单品同期在批发市场的批发价格附件3是这6个单品在2023年7月1日前的损耗率数据。数据量不大但信息密度高关键在于如何串联。我的核心思路是构建一个“预测-优化-决策”的闭环框架。首先必须明确题目中“自动定价”和“补货决策”是强耦合的定价影响销量销量决定库存和补货需求而补货成本批发价又反过来制约定价空间。因此不能孤立地看待这两个问题。我们的目标是在满足每日各单品需求由销量体现、控制损耗由历史损耗率约束、并尽可能提升商超收益售价与成本之差的前提下制定未来一周7月31日至8月6日每天的定价和补货量。这里的关键破题点在于对“收益”的理解。商超的收益不仅仅是销售额减去进货成本还必须考虑损耗成本。蔬菜是生鲜品当日未售出的部分会按一定比例损耗这是实实在在的损失。因此目标函数应该是最大化净利润即总销售额 - 总进货成本 - 总损耗成本。损耗成本的计算需要依赖附件3的历史损耗率并合理预测未来一周的损耗情况。这是一个典型的带有不确定性的优化问题。2. 数据预处理与特征工程从原始流水到模型可用的“燃料”附件1的销售流水数据是建模的基础但原始数据是交易级别的需要聚合到“单品-日期”的粒度。这一步看似简单却暗藏玄机处理不好会直接影响后续模型的准确性。2.1 销售数据聚合与异常值处理我们首先按单品和销售日期对附件1的销售流水进行聚合得到每个单品每天的销量公斤和销售单价元/公斤。这里立刻会遇到几个问题同一单品同一天可能有多个售价这是因为促销、时段差异或不同顾客群体造成的。简单地取平均或中位数可能会丢失信息。我们的处理方法是以销量为权重计算加权平均售价作为该单品当日的代表价格。这更能反映当日的实际收入情况。缺失日期某些单品在某些天可能没有销售记录。这不一定代表销量为0可能是数据记录缺失或当日确实未营业。我们需要结合附件2的批发价数据来判断。如果批发市场当日有该单品的价格通常认为商超是营业的那么销量缺失可能意味着销量极小或为0。对于建模我们更倾向于将其视为0并用插值法如前后天的均值或简单置0来处理但在后续需求预测时需要将这种“零值”作为一种特殊模式来考虑。异常值检查是否存在销量或价格远高于或低于正常范围的记录。例如某天某个单品销量激增可能是团购或记录错误。我们采用3σ原则三倍标准差结合业务判断进行筛选。对于明显不合理的极高值如价格是平时的10倍予以剔除并按缺失值处理。实操心得不要一上来就用复杂的插值算法。对于时间序列数据尤其是商业数据先用肉眼观察序列图。有时一个明显的异常点背后可能是一个真实的促销事件盲目剔除反而会丢失重要信息。我们团队的做法是将疑似异常点的日期标记出来结合是否周末、节假日虽然本题时间段内无重大节日进行交叉验证再决定是修正、剔除还是保留。2.2 批发价数据融合与成本序列构建附件2给出了批发市场的每日价格这是我们计算进货成本的关键。处理相对简单主要是检查与销售日期的对齐并处理可能的缺失。通常批发价数据比销售数据更完整。这里的关键是构建一个“成本基准线”。我们注意到批发价波动剧烈直接用它作为第二天的进货成本是合理的假设。因此对于未来一周7月31日-8月6日我们需要先预测批发价。2.3 损耗率数据的应用与扩展附件3给出了7月1日前的历史损耗率。这是一个静态参考值。在实际运营中损耗率与库存周转率、商品新鲜度可近似由在架时间衡量、季节等因素有关。题目只给了一个历史平均值我们在建模时有两种思路保守策略直接使用该历史平均值作为未来一周每天的固定损耗率。计算简单但可能不够精确。动态策略建立损耗率与库存量、销售量的关系模型。例如定义当日损耗量 前日库存结余 * 动态损耗率。动态损耗率可以设计为一个关于前日库存结余的递增函数库存越多管理越难损耗风险越高其具体参数可通过历史平均损耗率进行校准。这种方法更贴近现实但增加了模型复杂度。我们团队选择了折中的方案以历史损耗率为基础引入一个与当日未售出库存占比正相关的调整因子。例如若某单品当日补货100kg只售出60kg那么剩余40kg面临损耗风险其损耗率应在基础值上适当上调。3. 核心模型构建预测、优化与决策的三角支撑整个模型框架分为三层需求预测层、价格响应层、联合优化决策层。3.1 需求预测模型销量与批发价的双轨预测我们需要预测两个关键时间序列未来一周每个单品每天的销量和批发价。这是所有决策的基础。对于销量预测我们采用了SARIMA季节性自回归积分滑动平均模型。虽然数据只有30天但蔬菜销售有明显的周周期性周末 vs 工作日。我们首先对每个单品的历史销量序列进行平稳性检验ADF检验和季节性分解。由于数据量小我们更注重模型参数的简洁性避免过拟合。通常SARIMA的订单(p,d,q)和季节性订单(P,D,Q,s)中的s设为7周周期。通过网格搜索配合AIC准则确定最优参数。对于数据量小的单品我们也会尝试使用Prophet模型它对缺失值和趋势变化点有较好的鲁棒性且能直观地加入“周末”这个回归因子。对于批发价预测波动性通常比销量更大。我们除了使用SARIMA还尝试了简单但有效的基线模型以前一周7月24日-7月30日的均价作为未来每天的预测值或者使用“昨日价格”作为今日预测随机游走模型。对比发现对于某些波动剧烈的单品简单移动平均如3天移动平均的预测误差有时比复杂时间序列模型更小。因此我们最终采用了集成思路对每个单品分别计算SARIMA、Prophet和3日移动平均的预测值然后取中位数作为最终批发价预测。这提升了预测的稳健性。注意事项千万不要把销量预测和价格预测完全独立开。在现实中价格影响需求。但在本题的第一阶段预测中我们假设未来一周的销售价格尚未确定这正是我们要优化的因此预测的是在“当前定价策略”延续下的基线销量。更高级的做法是引入价格弹性建立需求与价格的关系模型但这需要更多数据来估计弹性系数。在本题数据有限的情况下我们选择分步处理先预测基线销量在优化模型中再考虑价格变动对销量的影响。3.2 价格响应函数连接定价与销量的桥梁这是将“自动定价”问题量化的核心。我们需要一个函数来描述当某个单品第t天的售价p_it偏离其某个“参考价格”时其销量d_it会如何变化。常用的价格响应函数有线性函数、指数函数和逻辑函数。我们选择了线性需求函数因其形式简单参数易于解释和标定d_it base_demand_it - elasticity_i * (p_it - reference_price_it)其中base_demand_it就是我们上一步预测得到的、在参考价格下的基线销量预测值。elasticity_i单品i的价格弹性系数0。弹性系数越大销量对价格越敏感。reference_price_it参考价格。这里我们采用了两个参考一是前一日售价p_i(t-1)代表消费者对历史价格的认知二是预测的当日批发价cost_it加上一个固定加成代表成本加成定价的基准。我们将两者加权平均作为最终参考价。弹性系数elasticity_i的估计是难点。我们利用历史30天的数据对每个单品以每日售价为自变量销量为因变量进行线性回归斜率即为弹性系数的估计。由于数据点少估计结果可能不稳定。我们采用了岭回归Ridge Regression来防止过拟合并将所有单品的弹性系数向一个全局均值进行收缩贝叶斯收缩以提高稳健性。3.3 联合优化模型以利润最大化为目标的数学规划有了预测的需求函数和成本我们就可以建立优化模型了。决策变量是未来7天、6个单品每天的售价p_it和补货量q_it。目标函数是最大化7天的总净利润。目标函数Maximize Σ_t Σ_i [ p_it * d_it(p_it) - cost_it * q_it - loss_cost_it ]其中d_it(p_it)就是上面价格响应函数计算出的销量它是p_it的函数。loss_cost_it是损耗成本。我们采用动态损耗率模型loss_cost_it unit_cost_i * (inventory_i(t-1) q_it - d_it) * dynamic_loss_rate_it。unit_cost_i用预测的批发价cost_it近似。dynamic_loss_rate_it基于历史损耗率和当日未售出库存比例计算。约束条件需求约束每日销量不能超过当日可用库存前日结余当日补货。即d_it inventory_i(t-1) q_it。库存动态inventory_it inventory_i(t-1) q_it - d_it。这是状态转移方程。补货量非负q_it 0。售价范围约束售价需在合理范围内。我们设定p_it cost_it * (1min_margin)以保证最低毛利率同时p_it max_price_imax_price_i可取历史最高售价的1.2倍。损耗率约束计算出的动态损耗率不能超过一个上限如历史损耗率的2倍以避免模型通过极端堆积库存然后高损耗来“虚增”需求的不合理情况。初始库存题目未给出7月30日的期末库存这是一个关键假设点。我们假设商超希望每日营业结束时库存清零或保持一个安全库存如次日预测销量的20%。因此我们可以将7月30日的库存作为可调整的参数或者直接假设为0从7月31日开始计算。更合理的做法是根据7月30日的销售和批发数据反推一个合理的期末库存作为初始值。这个优化模型是一个中等规模的非线性规划问题目标函数中含有p_it * d_it(p_it)而d_it是p_it的线性函数因此整体是二次型。我们使用Python的SciPy.optimize库或更专业的CVXPY库进行求解。由于变量较多7天6单品2变量84个直接求解全局最优可能困难。我们采用分解协调的思想先固定补货量q_it优化价格p_it再固定价格优化补货量迭代几次直至收敛。这通常能找到一个高质量的局部最优解。4. 模型求解、结果分析与可视化呈现4.1 求解策略与算法选择我们最终构建的模型是一个带有线性约束的二次规划问题。使用CVXPY描述问题并调用OSQP求解器可以高效求解。对于非线性更强的动态损耗率部分我们做了线性化近似处理预先根据预测的销量和补货量估算出每日末库存从而计算出估算的损耗率在单次优化中视为常数。在迭代协调时再根据优化出的新补货量和销量更新损耗率估计进行下一轮优化。通常迭代3-5轮后结果就会稳定。4.2 结果解读与业务洞察求解后我们得到了未来7天每个单品每天的推荐售价和补货量。分析这些结果能得出许多有价值的业务洞察定价策略高弹性单品如常见叶菜的价格波动应更谨慎建议采取“每日低价”策略价格围绕成本小幅波动。低弹性单品如特色蔬菜或必需品可以设置较高的毛利率。模型通常会建议在预计销量高的日子如周末提前小幅涨价并在进货成本低的日子降低售价以刺激销量、减少后续库存压力。补货策略补货量与预测销量、当前库存、价格策略强相关。模型会倾向于在批发价低的日子多补货成本低在预计售价高、销量好的日子确保库存充足。同时模型会严格控制每日末库存以避免高损耗。对于易损耗单品补货策略更加“精准”宁少勿多。利润贡献分析通过模型可以计算出每个单品在未来一周的利润贡献度。可以发现可能80%的利润来自2-3个单品。这提示商超可以重点优化这些核心单品的运营而对于利润贡献低的单品可以考虑简化其管理或调整品类。4.3 可视化与方案表达将结果用图表清晰呈现至关重要图1未来一周各单品价格与补货量热力图用颜色深浅直观展示每天每个单品价格高低和补货量多少。图2单品利润贡献堆积图展示每天总利润由哪些单品构成。图3库存与销量时序对比图对于某个重点单品绘制其未来7天预测销量、补货量、库存结余和损耗量的变化曲线直观展示模型如何平衡销售与损耗。表格决策方案表提供清晰的表格列明日期、单品编码、推荐售价、推荐补货量、预测销量、预测损耗量、预测毛利方便执行。5. 模型检验、灵敏度分析与常见陷阱5.1 模型检验与稳健性分析我们通过以下方式检验模型历史回测用7月最后一周24-30日的数据假设我们知道那周的批发价让模型基于之前的数据预测并决策然后将模型的推荐售价、补货量与实际情况对比。计算如果按照模型决策其预估利润与实际利润的差异。这能有效评估模型的有效性。关键参数灵敏度分析测试价格弹性系数elasticity_i、基础损耗率、初始库存等关键参数在合理范围内变动时最终总利润和决策方案的波动情况。如果利润对某个参数极其敏感说明模型在该参数上的不确定性风险高需要在报告中指出并建议商超重点监控该因素。5.2 参赛常见问题与避坑指南根据多年评审和指导经验队伍在解决此题时常犯以下错误预测与优化脱节最典型的错误是先预测未来7天“销量”然后基于预测销量去“优化”补货使其等于预测销量再单独定价。这完全忽略了价格对需求的调节作用以及库存、损耗、成本的联合影响。忽视损耗或处理过于简单很多队伍直接将损耗视为固定比例的成本忽略了损耗与库存水平的正相关关系。更糟糕的是有些模型甚至没有在目标函数中扣除损耗成本导致模型倾向于囤积库存。对价格弹性系数处理不当要么忽略弹性假设销量与价格无关要么用一个主观给定的弹性值用于所有单品。正确的做法是尝试从历史数据中估计并说明估计的局限性及采取的稳健性措施。模型求解不现实或未提供具体方案有些论文大谈特谈各种高级算法如深度学习、强化学习但给出的最终方案却模糊不清没有具体的、按日按单品的售价和补货量表格。评委看重的是可落地的决策支持。缺乏稳健性分析模型建立在诸多预测和假设之上如果不讨论这些假设不成立时的影响模型的实用性将大打折扣。编程实现与模型描述不符论文中描述的模型复杂精美但实际代码可能是另一个简单的模型。保持论文、代码、结果的一致性至关重要。最后的建议国赛C题往往注重解决实际问题的综合能力。清晰的逻辑主线、合理的假设、完整的建模流程、稳健的结果分析比追求模型的复杂度更重要。在论文写作中用“问题分析-模型建立-求解-结果分析-检验”的框架将上述思考过程有条理地呈现出来并配上关键代码片段和精美的图表就能形成一份有竞争力的作品。记住你的模型是为商超经理服务的最终要给他一张清晰明了的行动清单。