
1. 项目概述一次从零到一的数学建模实战复盘去年带队参加“认证杯”数学建模竞赛的经历至今记忆犹新。当时我们选的C题核心是围绕“共享汽车”的调度与布局优化问题。这题目听起来很“应用”但真做起来从问题抽象、模型构建到编程求解每一步都是对综合能力的考验。很多朋友对数学建模感兴趣但往往卡在“如何把现实问题变成数学语言”这一步或者模型建好了却不知道如何用SPSSPRO这类工具高效求解。今天我就以这道“破局共享汽车”的赛题为例完整复盘我们的求解全过程不仅分享最终的文档和程序思路更重要的是拆解我们当时的思考路径、踩过的坑以及那些让模型从“能用”到“好用”的关键技巧。无论你是正在备赛的学生还是对数据分析、运筹优化感兴趣的朋友相信这篇从一线实战中总结出的经验都能给你带来直接的启发。2. 赛题核心与破题思路拆解2.1 问题背景与核心矛盾识别当年的C题给了一个非常典型的城市共享汽车运营场景。题目描述了某城市几个区域的共享汽车租赁点给出了不同时间段如早高峰、晚高峰、平峰期各站点的历史租还车数据。问题核心直指共享汽车运营的“阿喀琉斯之踵”供需时空错配。简单说就是上班早高峰时居民区站点车被借空而商务区站点却堆积了大量闲置车辆到了晚高峰情况又完全反过来。这种“潮汐现象”导致用户无车可借或无位可还体验极差而运营方则要承担高昂的空驶调度成本。我们的首要任务就是精准定义这个矛盾。题目要求我们建立数学模型来优化调度策略即在何时、从何站点、调度多少车辆至何站点以在满足一定服务水平如用户等待时间不超过某个阈值的前提下最小化运营方的总成本。这里成本通常包括调度车辆的燃油或电耗成本、调度人员工时成本以及因车辆闲置或用户流失产生的隐性成本。识别出“成本最小化”与“服务水平约束”这一对根本矛盾是构建所有模型的起点。2.2 模型选型与思路确立面对这样一个动态调度优化问题常见的模型选择有几种线性/整数规划、网络流模型、排队论模型或者更现代的强化学习方法。我们团队经过讨论否决了过于复杂的强化学习比赛时间有限数据未必支持也认为单纯的排队论难以直接处理多站点、多时段的协同调度。我们的思路最终锚定在基于时空网络的混合整数线性规划模型上。为什么是MILP混合整数线性规划第一它能清晰地将调度决策整数变量从i站点到j站点的调度车次数、库存状态连续变量各站点各时刻的车辆数和逻辑约束如“只有有车可调时才允许调度”用数学公式表达。第二其目标函数总成本最小可以很方便地将固定成本、变动成本线性加权求和。第三像SPSSPRO、Lingo或调用Gurobi等求解器对中等规模的MILP问题求解效率很高适合比赛时限。这个模型的核心是构建一个“时空网络图”每个物理站点在不同时间点被复制成一个节点节点间的弧代表车辆在时间维度上的留存或空间维度上的调度。通过这种方式复杂的动态问题被“拍平”为一个可以静态求解的大型数学规划问题。注意模型选型没有绝对的对错只有是否适合。在比赛中清晰、可求解、能自圆其说的模型远比追求前沿但解释不清的模型得分高。MILP是这类资源调度问题的“经典且可靠”的选择。2.3 数据处理与关键参数估计题目给出的历史数据是建模的基石。数据通常包括各站点、各时段的租车需求量、还车量。但原始数据不能直接使用必须进行预处理和深度加工需求与供给的净流量计算对于每个站点s在每个时段t计算净流量 还车量 - 租车量。正值表示该站点车辆净流入容易产生淤积负值表示净流出容易产生短缺。这是调度需求的直接驱动信号。需求预测比赛通常提供的是历史数据但模型是针对未来调度的。因此我们需要用这些历史数据来预测未来相同时段如下一个工作日的需求。我们采用了简单的移动平均法并考虑了工作日与周末的模式差异。更高级的可以用时间序列模型如ARIMA但在有限时间内简单稳健的方法更可取。成本参数设定这是模型能否贴近现实的关键。调度成本主要包括与距离相关的变动成本元/公里和与次数相关的固定成本元/次。我们需要根据题目暗示或实际常识进行合理假设。例如假设调度车辆的平均时速、单位距离能耗成本从而将调度时间转化为成本。一个技巧可以将“用户等待导致的潜在流失”作为一种惩罚成本加入到目标函数中这样模型会在“调度成本”和“服务质量”之间自动寻找平衡点而不是将服务水平作为死板的约束。3. 混合整数线性规划模型构建详解3.1 模型符号定义与决策变量建立一个清晰的符号体系是第一步这能避免后续推导中的混乱。我们的定义如下集合( S )共享汽车站点集合索引 ( i, j )。( T )时间段集合例如将一天划分为24个时段或48个半小时段索引 ( t )。参数( D_{it} )站点 ( i ) 在时段 ( t ) 的预测租车需求量。( R_{it} )站点 ( i ) 在时段 ( t ) 的预测还车量。( c_{ij} )从站点 ( i ) 调度一辆车到站点 ( j ) 的成本与距离成正比。( f )每次调度发生的固定成本如司机启动成本。( cap_i )站点 ( i ) 的最大停车位容量。( I_{i0} )站点 ( i ) 在初始时刻( t0 )的车辆库存。( M )一个足够大的正数Big-M用于逻辑约束线性化。决策变量( x_{ijt} )整数变量。表示在时段 ( t ) 开始时从站点 ( i ) 调度到站点 ( j ) 的车辆数量。这是核心调度决策。( I_{it} )连续变量可整数。表示站点 ( i ) 在时段 ( t ) 开始时的车辆库存数。( y_{ijt} )0-1变量。表示在时段 ( t ) 是否发生了从 ( i ) 到 ( j ) 的调度用于触发固定成本。3.2 目标函数与约束条件推导目标函数是最小化总成本我们将其分为三部分变动调度成本、固定调度成本和库存失衡惩罚成本。[ \text{Minimize } Z \sum_{t \in T} \sum_{i \in S} \sum_{j \in S, j \neq i} (c_{ij} \cdot x_{ijt} f \cdot y_{ijt}) \lambda \cdot \sum_{t \in T} \sum_{i \in S} |I_{it} - \text{target}_{it}| ]其中( \lambda ) 是惩罚系数( \text{target}_{it} ) 是该站点该时段的理想库存水平例如设为该站点预测需求的一定比例。最后一项惩罚项是为了避免模型为了节省调度成本而让某些站点长期处于空置或爆满的极端状态使调度结果更均衡。绝对值可以通过引入辅助变量线性化。约束条件是模型的灵魂确保解的逻辑正确性库存平衡约束最核心站点 ( i ) 在时段 ( t1 ) 的库存等于上一时段库存加上本时段内还入的车辆和从其他站点调入的车辆减去租出的车辆和调往其他站点的车辆。 [ I_{i,t1} I_{it} R_{it} \sum_{j \neq i} x_{jit} - D_{it} - \sum_{j \neq i} x_{ijt}, \quad \forall i \in S, t \in T ] 这个约束将所有的决策变量和参数动态地联系在了一起。调度逻辑与固定成本约束只有当调度车辆数 ( x_{ijt} 0 ) 时对应的二进制变量 ( y_{ijt} ) 才应为1以计收固定成本。 [ x_{ijt} \leq M \cdot y_{ijt}, \quad \forall i,j \in S, i \neq j, t \in T ] [ y_{ijt} \in {0, 1} ] 这里 ( M ) 是一个上界可以取为站点容量或一个足够大的数。站点容量约束每个站点的库存不能超过其车位容量。 [ 0 \leq I_{it} \leq cap_i, \quad \forall i \in S, t \in T ]非负与整数约束 [ x_{ijt} \in \mathbb{Z}^, \quad I_{it} \geq 0 ]调度可行性约束可选但重要不能从库存为0的站点调出车辆。这可以通过库存平衡约束隐含但显式地加上可以加强模型有时能帮助求解器更快找到解。 [ x_{ijt} \leq I_{it}, \quad \forall i,j \in S, i \neq j, t \in T ]3.3 模型线性化与求解准备上述模型中目标函数里的绝对值项和约束中的“如果...那么...”逻辑已用Big-M法处理是典型的非线性或离散特征。MILP求解器如SPSSPRO内置的或连接的外部求解器可以直接处理这些。我们的工作是将模型按照求解器要求的格式进行整理。通常需要明确所有变量的类型和范围连续、整数、二进制。将目标函数和所有约束都化为线性形式。对于绝对值惩罚项 ( |I_{it} - \text{target}{it}| )我们引入两个非负辅助变量 ( u{it}^ ) 和 ( u_{it}^- )并添加约束 [ I_{it} - \text{target}{it} u{it}^ - u_{it}^-, \quad u_{it}^ \geq 0, \quad u_{it}^- \geq 0 ] 然后将目标函数中的绝对值项替换为 ( \lambda \cdot (u_{it}^ u_{it}^-) )。这样就完全线性化了。实操心得在比赛环境中模型的复杂度需要与求解时间平衡。如果站点数|S|或时段数|T|很大模型变量会急剧膨胀可能导致求解时间过长甚至无法求解。这时需要进行问题简化例如将距离过远、调度不经济的站点对之间的决策变量直接设为0将相邻时段合并以减少时间粒度或者先聚类站点在“区域”层面进行粗调度再细化。这些技巧能显著提升求解效率。4. 基于SPSSPRO的模型实现与求解4.1 SPSSPRO环境准备与数据导入SPSSPRO作为一款集成了多种统计与优化算法的平台对于求解MILP问题非常友好。我们首先在平台上创建了一个新项目。数据文件准备我们将处理好的参数整理成CSV文件。通常需要以下几个表distance_cost.csv: 列包括from_site,to_site,cost_per_car。表示调度一辆车的成本矩阵。demand_forecast.csv: 列包括site,time_period,demand,return。即每个站点每个时段的预测租还车量。site_info.csv: 列包括site,initial_inventory,capacity。站点的初始库存和容量。fixed_cost.csv: 可以是一个标量值或者如果不同线路固定成本不同也可以是一个矩阵。在SPSSPRO中导入数据使用平台的“数据上传”功能将这些CSV文件分别上传并确保它们被正确识别为数据集。为每个数据集起一个清晰的名称如dist_cost,demand,site_capacity。4.2 利用优化建模模块构建模型SPSSPRO的“优化”模块通常提供图形化或表单式的建模界面但更强大的方式是使用其脚本模式或直接调用求解器API。我们选择了后者因为它灵活性最高。定义集合和参数在优化模型设置中我们先定义索引集站点集合S、时段集合T。然后使用“导入数据”功能将之前上传的数据集映射到模型参数上。例如将distance_cost.csv映射为二维参数c[i,j]将demand_forecast.csv中的demand列映射为参数D[i,t]。定义决策变量在变量定义部分我们添加变量x[i,j,t]类型为“整数”下界为0。变量I[i,t]类型为“连续”下界为0上界对应cap[i]。变量y[i,j,t]类型为“二进制”。辅助变量u_plus[i,t],u_minus[i,t]类型为“连续”下界为0。输入目标函数在目标函数编辑框中按照线性化后的形式输入Minimize: sum((i,j,t), c[i,j]*x[i,j,t]) f * sum((i,j,t), y[i,j,t]) lambda * sum((i,t), u_plus[i,t] u_minus[i,t])注意求和符号需要按照SPSSPRO的语法来写通常是sum(索引, 表达式)的格式。输入约束条件这是最繁琐但也最关键的一步。我们需要将第3.2节推导的所有约束一条条地翻译成SPSSPRO的约束语法。库存平衡约束for each i in S, t in T: I[i,t] R[i,t] sum(j in S: j!i, x[j,i,t]) - D[i,t] - sum(j in S: j!i, x[i,j,t]) I[i, t1]。这里需要注意时段索引的边界处理最后一个时段t1可能不存在。Big-M约束for each i,j in S (i!j), t in T: x[i,j,t] M * y[i,j,t]。辅助变量约束for each i in S, t in T: I[i,t] - target[i,t] u_plus[i,t] - u_minus[i,t]。容量约束for each i in S, t in T: I[i,t] cap[i]。调度可行性约束for each i,j in S (i!j), t in T: x[i,j,t] I[i,t]。4.3 求解器配置与计算执行模型构建完毕后进入求解设置。选择求解器SPSSPRO可能内置或连接了多个求解器如COIN-OR CBC开源、Gurobi、CPLEX商业如果平台有许可。对于MILP问题Gurobi和CPLEX在速度和稳定性上通常表现更优。我们当时选择了可用的Gurobi求解器。设置求解参数时间限制比赛时间有限我们设置了最大求解时间例如1800秒。如果到时未求得最优解求解器会返回当前找到的最优可行解。最优间隙设置一个可接受的MIP Gap例如0.01或1%。这意味着当求解器证明当前解与理论最优解的目标值差距在1%以内时即可停止这能大幅缩短求解时间。线程数如果允许可以设置使用多线程并行计算加快求解速度。执行求解点击“求解”按钮。SPSSPRO会将模型编译成求解器可识别的格式如.lp或.mps文件并调用求解器进行计算。期间可以查看求解日志了解迭代过程、边界提升等情况。4.4 结果解读与调度方案输出求解完成后SPSSPRO会提供详细的结果报告。求解状态首先查看求解状态是“Optimal”找到最优解、“Feasible”找到可行解但可能未达最优还是“Infeasible”无可行解。如果是“Infeasible”就需要回头检查模型约束是否相互矛盾或者数据是否有误。目标函数值报告的最小总成本值是评估方案经济效益的核心指标。决策变量值这是我们需要提取的核心结果。我们需要导出变量x[i,j,t]的值即调度方案表。这个表清晰地列出了在哪个时段需要从哪个站点调度多少辆车到哪个站点。导出数据在SPSSPRO中可以将结果变量导出为新的数据集或CSV文件。我们导出了一个包含from_site,to_site,time,num_cars四列的调度计划表。库存轨迹同时导出变量I[i,t]的值生成各站点随时间变化的库存水平图表。这有助于我们直观地验证调度方案的效果是否避免了站点空置或爆满库存曲线是否变得比调度前更平稳注意事项第一次求解结果往往不是最终答案。需要仔细分析调度方案是否出现了不合理的、极长距离的微量调度比如只调度1辆车穿越整个城市这可能是因为成本参数设置不合理或者缺少对调度距离的额外约束。我们需要根据常识和业务逻辑对模型进行迭代调整例如增加约束“禁止距离超过D公里的站点间调度”或者调整成本函数使长距离调度成本呈非线性增长。5. 模型验证、灵敏度分析与方案评估5.1 方案可视化与直觉验证得到数学上的最优解后不能直接将其作为最终方案。我们必须将其“翻译”回业务场景进行直觉和逻辑上的校验。调度热力图我们利用导出的调度方案表用Python的Matplotlib或Seaborn库绘制了调度热力图。横轴是时间纵轴是站点对或调度流向颜色深浅表示调度车辆数。通过这张图可以一目了然地看到调度活动集中在哪些时段、哪些主要流向上例如早高峰从居民区流向商务区的深色带晚高峰的逆向深色带。这符合我们对“潮汐调度”的预期验证了模型的基本逻辑是正确的。库存对比曲线将优化后的各站点库存曲线与不进行调度仅靠用户自然租还的库存曲线放在同一张图上对比。优化的曲线应该波动更小更少触及0无车或容量上限无位的警戒线。这直观地证明了调度方案在平抑供需波动上的效果。关键指标计算车辆周转率优化后所有车辆的总服务订单数是否提升平均用户等待时间通过模拟或估算调度后因无车可借导致的用户等待时间是否显著下降调度里程与成本占比计算总调度里程占总行驶里程的比例以及调度成本在总收入中的占比评估调度方案的运营负担。5.2 灵敏度分析与策略洞察数学建模的魅力之一在于可以通过改变参数观察结果的变化从而获得深刻的业务洞察。我们在SPSSPRO中利用其“灵敏度分析”功能或通过手动多次运行模型探讨了以下几个问题调度固定成本的影响我们逐步提高每次调度的固定成本 ( f )。结果发现当 ( f ) 很低时模型倾向于频繁进行小批量调度以“精准匹配”瞬时需求当 ( f ) 升高到一定程度后模型会转向“批量调度”策略即积累更多的不平衡后再一次性调度更多车辆以减少调度次数。这为运营方决定是否雇佣专职调度员高固定成本还是利用用户激励如红包还车提供了量化依据。惩罚系数 ( \lambda ) 的权衡调整库存失衡的惩罚系数 ( \lambda )。( \lambda ) 很大时模型会不惜调度成本也要保持各站点库存接近理想水平服务质量高但成本也高( \lambda ) 很小时模型会容忍某些站点长时间低库存以节省调度成本。这揭示了服务水平和运营成本之间的帕累托前沿可以帮助管理者根据公司战略是追求市场份额还是短期利润确定最优的平衡点。需求预测误差的鲁棒性测试我们将输入的需求预测数据 ( D_{it} ) 和 ( R_{it} ) 人为地增加一个随机扰动例如±10%重新运行模型。观察最优调度方案和总成本的变化幅度。如果变化剧烈说明我们的调度策略对预测误差非常敏感不够稳健。这时我们可以考虑采用鲁棒优化或随机规划的模型框架将不确定性直接纳入模型虽然更复杂但得到的方案抗风险能力更强。5.3 模型优缺点总结与扩展方向经过完整的求解与分析我们对这个MILP模型有了更全面的认识优点结构清晰逻辑严谨将复杂的动态调度问题转化为静态数学规划思路直接易于理解和向评委解释。灵活性强可以方便地添加各种业务约束如单次调度车辆数上限、调度时间段限制如夜间才能调度、车辆电量约束等。求解成熟有高效的商业求解器支持能保证在合理时间内得到高质量的解。局限性与改进方向“确定性”假设模型假设未来需求是已知的预测值忽略了实际中的随机性。这是最大局限。改进方向是转向随机规划或数据驱动的鲁棒优化。计算复杂度当站点数N和时段数T很大时变量规模约为 ( O(N^2T) )求解会变慢。可采用分解算法如Benders分解、拉格朗日松弛将大问题拆解或使用启发式算法如遗传算法、模拟退火快速求取满意解。静态决策模型一次性做出全天所有决策属于“开环”优化。实际运营中可以根据实时情况重新优化。可以将其改进为滚动时域优化模型每过一段时间就用最新信息重新求解未来一段时间的调度计划。6. 参赛文档撰写与编程实现要点6.1 论文写作结构与核心内容数学建模竞赛的论文是展示工作的唯一窗口其重要性不亚于模型本身。我们的论文结构如下摘要重中之重采用“问题-方法-模型-结果-结论”五段式。用精炼的语言说明研究了什么问题建立了什么模型MILP时空网络模型采用了什么算法和工具SPSSPRO/Gurobi求解器得到了什么关键结果调度方案使总成本降低了X%平均等待时间减少了Y%并总结了主要结论和特色。问题重述与分析用自己的话梳理题目明确要解决的核心问题和子问题并分析问题的特点动态、多目标、带约束。模型假设与符号说明列出必要的、合理的假设如需求预测是准确的、调度瞬间完成等。给出完整、清晰的符号表。模型建立这是论文的主体。详细推导模型包括目标函数和每一个约束条件的数学公式和文字解释。解释为什么这样建模以及每个约束的实际意义。模型求解说明使用的软件和求解器描述数据处理过程、模型在SPSSPRO中的实现流程以及遇到的求解困难和解决方法如调整MIP Gap以加速。结果分析与验证展示核心结果调度方案表、库存对比图进行灵敏度分析并用直观的方式如图表、关键指标验证方案的有效性。模型评价与推广客观评价模型的优缺点如上一节所述并提出改进方向。简要说明模型稍作修改后可应用于共享单车、物流配送等其他资源调度场景。参考文献与附录规范引用参考文献。将重要的数据、冗长的代码核心部分或中间结果放在附录。6.2 编程实现与代码管理虽然SPSSPRO提供了图形界面但复杂的模型和后期分析仍需编程。我们主要使用Python作为辅助工具。数据预处理脚本用Python的Pandas库清洗、转换原始数据计算净流量进行简单的移动平均预测并生成SPSSPRO所需的CSV文件。结果后处理与可视化脚本求解完成后从SPSSPRO导出结果数据用Python的Matplotlib/Seaborn绘制调度热力图、库存对比曲线等。用Pandas计算各项业务指标。代码规范与注释即使时间紧张也尽量保持代码整洁。关键步骤添加注释说明对应模型的哪一部分。将不同功能的代码数据处理、模型构建、结果分析放在不同的脚本或Jupyter Notebook的Cell中便于管理和复查。版本管理使用Git或简单地将代码定期备份到网盘管理代码和论文版本。每次大的修改前都做一个提交避免灾难性错误。踩坑实录我们曾犯过一个错误在定义时空网络的时段时忽略了调度动作本身消耗的时间。假设调度需要1个时段那么从i站点在t时段初调出的车应该在t1时段初才能到达j站点。我们最初的模型没有考虑这个时间差导致库存平衡约束出现逻辑错误求出的解明显不合理。后来我们在库存平衡约束中将调入的车辆x[j,i,t]的到达时间修正为t1时段才解决了这个问题。这个细节提醒我们建模时必须仔细考虑每个决策在时间轴上的精确影响。7. 给未来参赛者的建议与延伸思考回顾整个参赛过程从破题到成文有几个点我认为对后来者至关重要。首先团队协作与时间管理是生命线。三个人必须明确分工一人主攻模型建立与推导数学好一人主攻编程与求解编程强一人主攻论文写作与图表绘制文笔好、逻辑清。但分工不分家需要频繁讨论确保思路同步。严格制定时间表将三天时间精确到小时留出足够的缓冲时间用于调试和修改论文。其次一定要做“减法”。比赛时间有限不要追求模型的“大而全”。抓住核心矛盾建立一个简洁、清晰、可求解的模型远比一个复杂但漏洞百出或无法求解的模型得分高。我们的MILP模型并非最前沿但它完整、自洽、能求解、结果可解释这就是成功的关键。最后可视化与讲故事能力。评委在短时间内要阅读大量论文清晰美观的图表和流畅的逻辑叙述能让你脱颖而出。你的论文不仅要展示“我们做了什么”更要讲清楚“我们为什么这么做”以及“结果意味着什么”。将冰冷的数字和公式转化为对业务有洞察力的结论。这道“破局共享汽车”的赛题本质上是一个经典的资源调度问题。其模型内核——在时空约束下进行成本最优的资源配置——具有极大的通用性。你可以思考如果将“共享汽车”换成“急诊室医护人员排班”、“电网中的储能电站调度”或是“云计算中的任务负载均衡”问题的数学结构是否似曾相识学会解一道题更重要的是学会解一类题的方法论。这才是数学建模竞赛乃至所有数据分析工作带给我们的最宝贵的财富。