ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

数学建模竞赛实战:基于线性规划与需求预测的定价补货决策模型

数学建模竞赛实战:基于线性规划与需求预测的定价补货决策模型 1. 项目概述一次高强度的解题思维拉练每年九月的全国大学生数学建模竞赛对于参赛学生而言不亚于一场为期三天的“学术马拉松”。2023年的C题延续了该赛事一贯的风格题目背景贴近现实数据看似庞杂目标明确但路径开放。它不是一道有标准答案的数学题而是一个需要你综合运用数学工具、编程能力和领域洞察力去构建、求解并诠释的“项目”。拿到“蔬菜类商品的自动定价与补货决策”这个题目时很多队伍的第一反应可能是懵的——既有时间序列的销售预测又有复杂的库存优化还要考虑定价策略感觉每个部分都能单独写一篇论文。但数学建模的魅力恰恰在于此它考验的是你如何将一个复杂的现实问题拆解、抽象、整合成一系列可量化、可计算的模型并最终给出一个逻辑自洽、有说服力的解决方案。本文将基于2023年C题进行一次深度的思路拆解与实战推演重点不在于给出一个“标准答案”而在于分享一套面对此类综合性赛题时如何构建解题框架、选择技术路线、规避常见陷阱的系统性思考方法。无论你是即将参赛的新手还是希望提升建模思维的老手相信这些从实战中沉淀下来的经验能为你提供直接的参考。2. 核心问题拆解与建模总览面对一个多目标、多约束的复杂问题最忌讳的就是一头扎进细节。首先必须站在高处看清全貌。2023年C题的核心诉求非常清晰根据历史销售数据为商超制定未来一周2023年7月1-7日的单品定价与日补货计划。但“清晰”的背后是几个环环相扣的子问题。2.1 问题结构的四层递进关系我们可以将整个问题分解为四个具有逻辑依赖关系的层次数据理解与特征工程层这是所有工作的基石。题目提供了六个品类的蔬菜在2023年6月24-30日的销售流水、批发价格以及损耗数据。你需要首先理解每个字段的含义如单品编码、销量、售价、成本价识别数据的特性是否是面板数据是否存在缺失或异常并从中提取对预测和决策有用的特征。例如每个单品前几天的销量趋势、是否周末、批发价的波动情况、历史损耗率等。需求预测层这是定价和补货的前置输入。你必须预测未来七天7月1-7日每个单品每天的销量。预测的准确性直接决定了后续决策的质量。这里面临的核心挑战是历史数据只有一周7天样本量极少这对传统时间序列模型如ARIMA是巨大考验。因此如何利用有限数据、结合品类特性进行有效预测成为第一个技术难点。定价决策层在预测销量的基础上结合成本批发价和可能的损耗以商超盈利为目标为每个单品制定每日售价。定价不是孤立的它会影响销量需求弹性而销量又反过来影响库存和损耗。因此定价模型需要与需求预测进行某种形式的耦合或迭代。补货决策层在给定定价和预测销量的前提下决定每天每个单品的补货量。目标是满足需求的同时最小化总成本包括进货成本、库存持有成本和损耗成本。补货决策受到保鲜期、库存容量、每日销量波动等多重约束。这四个层次并非完全串联而是存在反馈。例如一个激进的定价策略可能抑制需求导致预测销量下降进而影响补货量。在简化模型中我们通常采用“先预测再定价最后补货”的序贯决策流程在更精细的模型中则可能需要建立联合优化模型。2.2 模型选型的核心考量在简单与复杂间权衡在三天竞赛的高压环境下模型选型的首要原则是“可实现性”和“可解释性”而非一味追求复杂。对于需求预测由于数据量极小指数平滑法Exponential Smoothing或移动平均法这类简单稳健的方法往往是首选。它们对短期趋势有较好的捕捉能力且计算简单。更高级的思路是引入外部特征例如将“星期几”作为哑变量或者利用同类单品同品类的销售数据建立聚合-分解模型先预测品类总销量再按历史比例分解到单品这可以有效缓解数据稀疏问题。强行使用LSTM、XGBoost等复杂模型很可能因数据不足而导致严重过拟合。对于定价与补货这是一个典型的运筹学优化问题。核心是定义决策变量每日售价、补货量、目标函数总利润最大化或总成本最小化和约束条件如售价范围、库存上下限、保鲜期约束。可以直接建立线性规划LP或整数规划IP模型。目标函数可以细化为总利润 销售收入 - 采购成本 - 损耗成本。其中销售收入依赖于“售价 × 销量”而销量又受售价影响需求弹性。这里一个关键的简化处理是假设在短期一周内需求弹性不变即销量与售价呈简单的线性或对数线性关系其参数可以从历史数据中粗略估计。这样整个优化模型就可以线性化或近似线性化方便用MATLAB的linprog或Python的PuLP、SciPy库求解。注意很多队伍在建立优化模型时忽略了损耗成本的计算。损耗不是简单的“没卖完就扔掉”题目给出了损耗率数据。在模型中损耗成本应体现为损耗成本 采购单价 × 补货量 × 损耗率。更精细的模型可以考虑损耗率随库存时间增加而升高。3. 分步实战从数据到决策的完整推演下面我们以一个具体品类例如“花叶类”中的某个单品为例演示一个完整的、可操作的建模流程。3.1 第一步数据清洗与探索性分析EDA拿到数据不要急着建模。用Python的Pandas进行初步探索import pandas as pd import matplotlib.pyplot as plt # 假设已加载销售流水表sales和批发价表cost print(sales.head()) print(sales.describe()) print(sales.isnull().sum()) # 检查单一单品例如编码101的历史销售趋势 single_item sales[sales[单品编码] 101].sort_values(日期) plt.figure(figsize(10, 5)) plt.plot(single_item[日期], single_item[销量(千克)], markero) plt.title(单品101过去一周销量趋势) plt.xlabel(日期) plt.ylabel(销量(千克)) plt.grid(True) plt.show() # 计算每日毛利率 single_item[毛利率] (single_item[销售单价(元/千克)] - single_item[批发价格(元/千克)]) / single_item[销售单价(元/千克)] print(single_item[[日期, 销量(千克), 销售单价(元/千克), 批发价格(元/千克), 毛利率]])实操心得这短短一周的数据中周末6月24-25日的销量往往有明显峰值。务必通过可视化确认这一模式并在特征工程中将其作为一个关键哑变量is_weekend加入。此外观察批发价是否稳定。如果波动大在预测未来成本时不能简单使用历史均值可能需要考虑使用最近一日的价格或一个保守的估计值。3.2 第二步需求预测模型构建鉴于数据只有7个时间点我们采用霍尔特-温特斯指数平滑法Holt-Winters因为它能同时捕捉水平、趋势和季节性。虽然我们只有一周数据但可以假设存在“周内”季节性以7天为周期。实际上由于数据仅包含一个周期我们更多是利用其平滑思想。一个更务实且可解释的做法是加权移动平均结合星期特征def predict_demand(historical_sales, future_dates): historical_sales: 单品过去7天的销量列表 future_dates: 未来7天的日期列表用于判断星期几 predictions [] # 计算历史日均销量作为基线 base_demand np.mean(historical_sales) # 计算历史数据中周末假设周六、周日相对于工作日的平均增幅 # 这里需要根据历史日期判断周末简化演示 weekend_boost 1.2 # 假设周末销量比平日高20%该值应从历史数据中计算得出 for date in future_dates: # 判断未来日期是否是周末 if date.weekday() in [5, 6]: # 5周六, 6周日 pred base_demand * weekend_boost else: pred base_demand # 可以加入一个简单的衰减趋势例如认为一周后期需求可能略有下降保鲜期影响 # 这里仅为示例更复杂的趋势需要更多假设 predictions.append(pred) return predictions关键点解析对于数据极度短缺的情况“基于规则的预测”往往比复杂的“黑箱模型”更可靠。上述方法的核心逻辑是1. 确定一个基础需求量历史平均。2. 根据星期几施加一个调整系数从历史数据中统计得出。3. 可以考虑加入一个随时间缓慢衰减的因子模拟蔬菜新鲜度下降导致的需求减弱。这种方法虽然简单但所有参数都有明确来源和解释在论文中易于阐述。3.3 第三步定价与补货联合优化模型这是整个赛题最核心的部分。我们建立一个以最大化未来七日总利润为目标的线性规划模型。决策变量p[i]: 第i天i1..7的销售单价元/千克q[i]: 第i天的补货量千克s[i]: 第i天的预测销量千克这是一个由p[i]决定的变量需要建立关系。模型假设与公式化需求函数假设销量与价格呈线性关系s[i] a - b * p[i]。其中a和b为需求弹性系数。如何估计可以利用历史7天的价格销量数据点做一元线性回归粗略得到a_hat和b_hat。注意这只是一个高度简化的估计实际中需求弹性可能很复杂。损耗假设每日末未售出的商品会按一个固定比例loss_rate从题目给出的损耗数据中计算产生损耗损耗成本按采购价c[i]计算。库存动态I[i] I[i-1] q[i] - s[i]其中I[0]为初始库存题目给出。目标函数最大化总利润。总利润 Σ ( p[i]*s[i] - c[i]*q[i] - c[i]*loss_rate*max(0, I[i-1]q[i]-s[i]) )其中第三项是损耗成本我们假设只有当天未售出的部分即补货后库存减去销量才产生损耗。约束条件售价范围p_low p[i] p_high可根据历史售价的上下浮动一定百分比设定。补货量非负q[i] 0。库存容量限制I[i] I_max题目可能给出或需假设。销量非负且不超过可用库存0 s[i] I[i-1] q[i]。需求函数关系s[i] a_hat - b_hat * p[i]这是一个将定价和销量关联的关键约束。使用Python PuLP库求解示例from pulp import LpProblem, LpVariable, LpMaximize, lpSum, value # 初始化问题 prob LpProblem(Vegetable_Pricing_Replenishment, LpMaximize) # 参数定义 days range(1, 8) a 100 # 需求函数截距示例值 b 2 # 需求函数斜率示例值 c [5.0]*7 # 未来七天采购成本示例值假设不变 loss_rate 0.05 # 日损耗率 I0 50 # 初始库存 I_max 200 # 最大库存容量 p_low, p_high 8.0, 15.0 # 售价上下限 # 定义决策变量 p LpVariable.dicts(Price, days, lowBoundp_low, upBoundp_high) # 售价 q LpVariable.dicts(Replenish, days, lowBound0) # 补货量 s LpVariable.dicts(Sales, days, lowBound0) # 销量 I LpVariable.dicts(Inventory, days, lowBound0, upBoundI_max) # 库存 # 设置初始库存 I[0] I0 # 目标函数总利润最大化 profit_expr lpSum([p[i]*s[i] - c[i-1]*q[i] - c[i-1]*loss_rate*(I[i-1] q[i] - s[i]) for i in days]) prob profit_expr # 约束条件 for i in days: # 库存动态平衡约束 prob I[i] I[i-1] q[i] - s[i] # 需求函数约束线性近似 prob s[i] a - b * p[i] # 销量不能超过可用库存 prob s[i] I[i-1] q[i] # 求解问题 prob.solve() # 输出结果 for i in days: print(fDay {i}: Price{value(p[i]):.2f}, Replenish{value(q[i]):.2f}, Sales{value(s[i]):.2f}, Inventory{value(I[i]):.2f}) print(fTotal Profit: {value(prob.objective):.2f})模型解读这个模型将定价和补货决策统一在一个框架下。通过求解这个线性规划我们直接得到了未来七天最优的每日售价和补货量。其中需求函数s a - b*p是连接定价与销量的桥梁。在实际应用中a和b的估计至关重要且非常脆弱。一个稳健的做法是进行敏感性分析测试不同的a,b值观察最优解的变化并在论文中讨论这种不确定性对决策的影响。4. 模型深化与拓展方向上述流程提供了一个基础且可实现的框架。但要冲击更高奖项必须在模型深度和创新性上做文章。以下是几个可行的深化方向4.1 需求预测的进阶策略品类层级建模对数据极度稀疏的单品放弃直接预测转而采用“自上而下”的方法。先预测整个品类的日总需求量数据更稳健再根据每个单品历史销售额占比将总需求分配下去。这需要对占比的稳定性进行分析或建立占比随时间如星期几变化的调整模型。引入外部变量虽然题目只给了销售数据但可以合理假设并建模。例如价格弹性本身可以作为变量。可以建立面板数据模型利用不同单品在同一时间点的数据估计出品类通用的价格弹性系数再应用于各个单品。集成学习应对不确定性采用多种简单模型移动平均、指数平滑、线性回归分别预测然后对其结果进行加权平均或区间估计得到一个带有置信区间的预测范围为后续的鲁棒优化提供输入。4.2 定价-库存联合优化模型的改进动态规划框架将问题视为一个有限阶段的随机动态规划问题。每天是一个阶段状态是当前库存水平决策是定价和补货量目标是最大化期望总利润。需求可以建模为随机变量其分布来自预测的置信区间。这种方法理论上更优但建模和求解尤其是维度诅咒难度极大通常需要简化如离散化状态空间才能实现。报童模型的扩展经典的报童模型解决单周期、随机需求下的库存问题。本题是多周期问题但可以借鉴其思想。对于每个单品每一天可以计算一个“临界分位数”作为决定补货量的依据同时将价格作为影响需求分布参数的杠杆。鲁棒优化考虑到需求预测的不准确性可以采用鲁棒优化方法。即假设需求在一个不确定集合内波动例如预测值±20%然后寻找一个在最坏情况下性能最好的max-min定价补货策略。这能极大提升方案的稳健性。4.3 考虑现实约束的细化保鲜期与生命周期不同蔬菜保鲜期不同。可以在模型中增加约束商品在进货后第k天必须售出否则全部损耗。这需要引入“商品年龄”作为状态变量模型会急剧复杂化但更贴近实际。捆绑销售与替代效应题目中品类内部单品可能存在替代或互补关系。例如菠菜价格升高消费者可能转而购买油菜。可以在需求函数中引入交叉价格弹性但这需要非常强的数据支持和假设谨慎使用。多目标优化除了利润商超可能还关注销售额、市场占有率、客户满意度与缺货率相关。可以建立多目标优化模型使用帕累托前沿来展示利润与缺货率之间的权衡。5. 论文写作与常见陷阱规避数学建模竞赛成果最终体现在论文上。思路再巧妙模型再复杂如果表达不清也会功亏一篑。5.1 论文结构黄金法则摘要重中之重用精炼的语言概括问题、方法、模型、算法、主要结果和结论。避免细节突出亮点。例如“针对蔬菜定价补货问题本文构建了基于加权需求预测与线性规划联合优化的决策模型。首先通过引入星期特征改进指数平滑法进行销量预测进而建立以利润最大化为目标、考虑损耗与库存约束的线性规划模型求解得到未来七日最优定价与补货计划。最后通过敏感性分析验证了模型鲁棒性并为商超提供了管理启示。”问题重述与分析不要照抄题目用自己的话梳理问题的背景、目标和限制条件并画出逻辑框图清晰地展示你对问题的分解思路如本文2.1节所示。模型假设列出所有关键假设并说明其合理性。例如“假设短期内单品需求与售价呈线性关系”、“假设不同单品间的需求相互独立”、“假设损耗仅发生在每日营业结束后”等。好的假设是简化问题的关键。符号说明用三线表清晰列出所有模型中使用的变量、参数及其含义、单位。模型建立与求解这是核心章节。对应你的建模步骤分小节阐述。每一部分都应包括动机为什么用这个模型、模型详细公式、参数估计方法、求解算法用了什么软件/函数。公式要编号并辅以必要的文字解释。模型检验与结果分析展示运行结果图表并对结果进行深入分析。必须进行敏感性分析改变关键参数如需求弹性系数b、损耗率观察结果如何变化并讨论其管理意义。这能极大提升论文深度。模型评价与推广客观评价模型的优点创新、实用、稳健和缺点假设较强、数据有限等并提出可能的改进方向。将模型推广到更一般的场景。5.2 实战中极易踩中的“坑”坑一忽视数据量滥用复杂模型。用LSTM预测7天数据后的未来7天是典型的“用大炮打蚊子”结果必然过拟合预测曲线可能非常奇怪。评委一眼就能看出问题。坑二模型“黑箱化”缺乏解释。只扔出一个复杂的模型代码和结果不解释中间参数如何得来、为什么这样设置。论文需要让一个不懂你所用算法的人能理解你的逻辑。坑三优化模型不考虑求解可行性。建立了一个非线性的动态规划模型却无法在论文中给出具体的求解过程和数值结果只能空谈理论。竞赛中能求解并给出具体数字结果的模型远胜于一个精美但无法实现的模型。坑四结果分析流于表面。只给出“定价提高了3%利润增加了5%”这样的描述。深度的分析应该是“当需求弹性系数b降低10%即需求对价格更不敏感时模型给出的最优定价平均上浮了8%总利润提升12%。这表明在当前市场环境下消费者对价格波动容忍度较高商超可采取更积极的定价策略。”坑五编程与论文脱节。论文中的结果、图表必须来自你实际运行的代码。确保代码可复现并在附录中给出核心代码片段不宜过长。三天时间从审题到成文是对体力、脑力和团队协作的极限挑战。对于2023年C题这类综合性问题取胜的关键往往不在于使用了多么高深的算法而在于对问题的清晰解构、对模型的合理简化、对假设的充分论证以及将整个思考过程清晰、严谨、有说服力地呈现出来。从数据清洗的一个简单判断到优化模型中的一个约束条件每一步都体现着建模者的思考深度。希望这份超详细的思路拆解能帮助你构建起应对这类赛题的肌肉记忆在未来的竞赛中从容地将一个复杂的现实问题转化为你笔下逻辑严密、闪耀着智慧光芒的解决方案。
返回列表