数学建模竞赛实战:机场出租车调度问题的仿真建模与优化策略

发布时间:2026/8/7 3:56:31
数学建模竞赛实战:机场出租车调度问题的仿真建模与优化策略 1. 项目概述从一道赛题到一套完整的解决方案看到“2019年国赛高教杯数学建模C题机场的出租车问题”这个标题很多参加过数学建模竞赛的朋友尤其是对运筹优化、排队论或者交通流问题感兴趣的同学应该会心一笑。这道题可以说是当年国赛的一道“明星题”它把一个看似日常的机场出租车调度问题抽象成了一个融合了随机过程、优化决策和经济效益分析的复杂数学模型。我当年作为指导老师带着学生啃下这道题过程中踩了不少坑也积累了很多从读题、建模到编程求解的实战心得。今天我就以这道题为蓝本抛开那些教科书式的泛泛而谈从头到尾拆解一遍解题的全过程重点分享那些论文里不会写、但实际做的时候至关重要的细节和技巧。无论你是正在备赛的学生还是对数学建模感兴趣的新手这篇文章都能给你提供一套可以直接“抄作业”的完整框架和避坑指南。这道题的核心场景非常生活化飞机抵达后旅客要去出租车上客点排队乘车而出租车则在蓄车池排队等待进入上客点。问题在于出租车司机面临一个决策——当蓄车池队伍很长时是继续排队等待可能到来的“长途客”收益高但等待时间长还是空载离开去市区揽客避免等待但可能错过高收益赛题要求我们建立数学模型研究司机的决策并对机场管理部门提出调度建议。这本质上是一个在不确定环境下的序列决策问题涉及到了排队论、收益评估、动态规划或仿真模拟等多个数学建模的核心工具。接下来我们就一步步拆开揉碎了讲。2. 核心问题拆解与建模思路确立面对一个数学建模赛题最忌讳的就是一头扎进去就开始列方程。第一步也是最重要的一步是精准地拆解问题把一段充满生活气息的文字描述翻译成数学语言明确界定的子问题。2.1 题目关键信息提取与假设合理化原题给出了几个关键条件和数据这里我根据记忆和常见设定还原具体以原题为准流量数据机场的航班到达服从某种分布如泊松过程从而决定了旅客到达出租车上客点的流量。旅客目的地旅客行程距离有长有短通常假设服从一个特定的概率分布如对数正态分布长途客比如去远郊区单价高短途客去附近单价低。双队列系统存在“旅客等候队列”和“出租车蓄车池队列”两个排队系统。司机决策点出租车进入蓄车池后司机能实时观察到两个队列的长度或等待时间并据此决定是继续排队还是“空载离开”即放弃本次排队直接驶离机场。我们的建模目标很明确目标一司机侧建立一个决策模型告诉司机在观察到特定队伍长度时如何选择等待/离开才能最大化自己的单位时间期望收益。目标二管理侧基于司机的理性决策模型分析不同管理措施如设置“短途票”专用通道、动态调度信息提示等对系统整体效率如旅客平均等候时间、出租车平均收益、空载离开率的影响。这里就要做第一个重要的合理化假设。现实中司机不可能精确知道下一位旅客的目的地。因此我们必须假设司机决策时只知道旅客行程的总体概率分布而不知道具体下一个客人的行程。他的决策是基于“期望收益”的计算。这是一个典型的风险决策模型。2.2 核心数学模型框架选择明确了问题接下来就是选择建模武器。这道题至少有三种主流建模思路各有优劣排队论博弈论框架这是最经典、最受评委青睐的思路。将旅客到达和出租车到达视为两个独立的泊松流服务台就是上客点。司机的决策可以看作一个“排队博弈”——每个司机都根据当前队列状态决定是否加入排队或退出离开。我们可以尝试建立生灭过程模型求解系统的稳态概率分布进而计算各项指标。这个方法的优点是理论扎实模型漂亮。但难点在于司机的决策会使系统的到达率出租车有效加入排队变成状态的函数导致模型非线性解析求解非常困难通常需要借助数值方法或仿真验证。基于仿真的智能体建模这是实操性最强、最容易出彩的思路。使用诸如NetLogo, AnyLogic或Python (SimPy库)来构建一个离散事件仿真模型。我们定义两类智能体“旅客”和“出租车”。旅客智能体属性包括到达时间、行程距离出租车智能体属性包括位置、状态空载、载客、等待、决策逻辑。司机的决策逻辑可以用一个简单的规则函数来实现例如if 预计等待时间 某个阈值则离开。通过大量重复仿真我们可以统计出各种指标并且可以非常方便地测试不同管理策略的效果。这个方法的优点是直观、灵活能处理复杂逻辑论文结果展示丰富各种趋势图。缺点是对编程能力要求稍高且需要解释清楚仿真模型的信度为什么仿真是合理的。动态规划/马尔可夫决策过程将司机的决策过程形式化为一个马尔可夫决策过程。定义状态为蓄车池队列长度旅客队列长度动作是“等待”或“离开”状态转移概率由航班到达和旅客行程分布决定回报是收益载客收入减去等待时间成本。然后求解这个MDP的最优策略例如使用值迭代算法。这个方法的理论层次最高能直接求出最优决策表。但计算复杂度可能很高特别是当状态空间较大时。我的实战建议是采用“仿真模型为主理论分析为辅”的混合策略。在论文中先用排队论知识对系统进行定性分析建立收益期望的数学表达式阐述司机决策的逻辑。然后重点构建一个离散事件仿真模型将前面的数学逻辑代码化通过仿真来定量验证分析结论并探究管理策略。这样既能体现理论深度又能保证结果的可靠性和论文的丰满度。3. 模型构建与关键公式推导我们选择仿真为主的方法但仿真中的每个核心模块都需要数学公式来定义。这是模型的“灵魂”。3.1 司机收益期望的计算模型这是整个问题的核心。司机在蓄车池中位于第n位。他需要估算如果选择等待直到他接上客人的期望净收益。等待时间成本假设司机单位时间的成本为C_w可以理解为油费、时间机会成本。如果他前面有n-1辆车旅客队列长度为m那么他需要等待的时间取决于服务速率上客速度和队列的动态变化。一个简化的估算方法是假设系统处于近似稳定状态平均服务率为μ车/分钟。那么他的预计等待时间T_wait ≈ (n m) / μ。这是一个非常关键的简化在仿真中我们可以动态计算更精确的时间。载客收入期望接到一位旅客收入取决于行程距离S随机变量服从分布F(s)和单价p。期望收入E[Revenue] p * E[S]。但这里有个陷阱如果接到的是短途客司机开回机场可能需要再次排队这趟活的实际净收益会降低。题目中常会引入“短途客”概念即行程小于某个阈值S0的旅客送完他们后返回机场可能允许不排队直接进入蓄车池有优先权或专用道但这需要额外建模。我们首先考虑基础情况期望毛收入 p * E[S]。决策规则司机比较两个选项选项A离开立即空载驶离前往市区揽客。假设驶离后到接到下一客人的平均时间和收入为T_away和R_away。那么离开的期望单位时间收益U_leave R_away / (T_away t_to_city)其中t_to_city是到市区的时间。选项B等待等待T_wait时间后获得期望收入E[Revenue]。那么等待的期望单位时间收益U_wait (E[Revenue] - C_w * T_wait) / T_wait。司机的决策规则可以简化为如果U_wait U_leave则等待否则离开。在实际仿真中U_leave可以设为一个外部给定的常数参数代表机场周边运营的平均收益水平。司机通过与这个“机会成本”比较来做决策。3.2 系统动态的离散事件仿真设计我们用伪代码来描述仿真核心逻辑。主要事件类型有航班到达、旅客到达上客点、出租车到达蓄车池、出租车接客离开、出租车返回/离开决策。# 伪代码/结构说明 初始化仿真时钟、队列、统计变量 设置仿真结束时间如24小时 while 仿真时钟 结束时间 获取下一个最早发生的事件 将仿真时钟推进到该事件时间 处理该事件 if 事件类型 “航班到达” 根据航班大小生成一批旅客按一定延迟加入到“旅客队列” 安排下一个“航班到达”事件按泊松过程间隔 elif 事件类型 “出租车到达蓄车池” 将出租车加入“蓄车池队列”末尾 立即触发该出租车的“决策事件” elif 事件类型 “出租车决策” 计算该司机当前的 U_wait (基于当前队列长度和期望收入) if U_wait U_leave 状态置为“等待中”不触发新事件等待被召唤 else 状态置为“空载离开”记录离开时间从队列移除 安排该出租车一段时间后可能“返回机场”或进入其他状态 elif 事件类型 “接客离开” if 旅客队列和蓄车池队列均不为空 从旅客队列头部移除一名旅客 从蓄车池队列头部移除一辆出租车 根据旅客行程分布随机生成本次行程距离 S 计算本次收入 Revenue p * S 记录该出租车的收益、服务时间 更新系统服务计数 安排该出租车“送客完毕返回”事件时间路程时间关键细节1决策触发时机。不是所有出租车每秒都在决策。更高效的实现是仅当队列状态发生改变时有车到达/离开或有旅客到达才触发队列中受影响车辆的重新决策。例如一辆新出租车加入蓄车池队尾它需要立即做决策。而它前面的一辆车因为等待时间变长队伍变长也可能需要重新评估是否继续等待。这能更真实地模拟司机的“观望”行为。关键细节2短途客的处理。如果赛题明确了短途客的处理规则例如送短途客的出租车可以凭票快速返回蓄车池那么需要在仿真中增加对应的逻辑和状态。这通常会显著影响司机的决策因为接到短途客的“惩罚”变小了司机更愿意冒险等待。4. 编程实现与参数校准模型建立后就需要用代码把它实现出来。这里我强烈推荐使用Python SimPy库。SimPy 是专门用于离散事件仿真的库能极大地简化事件调度和资源管理的代码。4.1 基于SimPy的仿真程序核心结构import simpy import random import numpy as np import pandas as pd from collections import defaultdict class AirportTaxiModel: def __init__(self, env, passenger_arrival_rate, taxi_arrival_rate, ...): self.env env self.passenger_queue [] # 旅客队列 self.taxi_queue [] # 出租车蓄车池队列 self.stats defaultdict(list) # 统计字典 # 启动持续运行的过程 self.env.process(self.passenger_generator(passenger_arrival_rate)) self.env.process(self.taxi_generator(taxi_arrival_rate)) def passenger_generator(self, rate): 生成旅客到达事件 while True: yield self.env.timeout(random.expovariate(rate)) # 生成旅客行程距离 trip_distance self.generate_trip_distance() self.passenger_queue.append({arrival_time: self.env.now, distance: trip_distance}) self.trigger_decision_for_all_taxis() # 旅客到达触发所有出租车重新决策 self.try_match() # 尝试匹配旅客和出租车 def taxi_generator(self, rate): 生成出租车到达蓄车池事件 while True: yield self.env.timeout(random.expovariate(rate)) taxi_id len(self.taxi_queue) self.taxi_queue.append({id: taxi_id, arrival_time: self.env.now, status: waiting}) self.make_decision(taxi_id) # 新车到达立即决策 def make_decision(self, taxi_index): 出租车决策过程 taxi self.taxi_queue[taxi_index] if taxi[status] ! waiting: return # 计算当前等待位置、预计等待时间 n_ahead taxi_index # 前面有多少车 m_passenger len(self.passenger_queue) expected_wait_time (n_ahead m_passenger) / SERVICE_RATE # 计算期望收益 expected_revenue FARE_PER_KM * EXPECTED_TRIP_DISTANCE u_wait (expected_revenue - COST_PER_MIN * expected_wait_time) / expected_wait_time # 决策 if u_wait U_LEAVE_THRESHOLD: taxi[status] committed else: # 选择离开 taxi[status] leaving self.stats[departure_time].append(self.env.now) # ... 从队列中移除需小心处理索引 # 可以安排一个未来返回的事件 # self.env.process(self.taxi_return(taxi_id)) def trigger_decision_for_all_taxis(self): 队列状态变化触发所有等待中出租车重新决策 for i, taxi in enumerate(self.taxi_queue): if taxi[status] in [waiting, committed]: self.make_decision(i) def try_match(self): 尝试将队首的旅客和出租车进行匹配 while self.passenger_queue and self.taxi_queue: # 找到队首且状态为‘committed’的出租车 for i, taxi in enumerate(self.taxi_queue): if taxi[status] committed: passenger self.passenger_queue.pop(0) # 服务该乘客 self.env.process(self.serve_passenger(i, passenger)) break else: break # 没有 committed 的出租车退出循环 def serve_passenger(self, taxi_index, passenger): 服务乘客过程 taxi self.taxi_queue.pop(taxi_index) service_time LOADING_TIME # 上客时间 yield self.env.timeout(service_time) # 记录收益 revenue FARE_PER_KM * passenger[distance] self.stats[revenues].append(revenue) self.stats[trip_distances].append(passenger[distance]) # 出租车进入“载客中”状态一段时间后返回或进入其他逻辑 trip_time passenger[distance] / AVERAGE_SPEED yield self.env.timeout(trip_time) # 出租车可能返回蓄车池或直接离开取决于行程长短等规则 # self.env.process(self.taxi_return(taxi[id]))注意以上代码是一个高度简化的框架示例重点展示SimPy的流程控制和核心逻辑。实际实现中队列操作特别是中间元素的移除需要更谨慎的数据结构如使用deque或维护索引短途客逻辑、出租车返回逻辑、更精确的等待时间估算等都需要完整实现。4.2 参数设定与模型校准模型参数不能乱设需要基于常识或题给数据或者通过敏感性分析来说明。旅客到达率根据航班到达率和大致每航班旅客数估算。例如平均每小时10个航班每个航班200人其中50%打车则旅客到达率约为(10*200*0.5)/60 ≈ 16.7 人/分钟。在仿真中用泊松过程的间隔时间expovariate(16.7)来生成。出租车到达率这通常是一个需要调节的参数用于模拟不同的供需关系。可以从“基本无等待”到“严重拥堵”设置多个场景。行程距离分布题目可能给出均值和方差。常用对数正态分布来模拟非负的、右偏的行程数据很多短途少数长途。np.random.lognormal(mean, sigma)。单位时间成本C_w和离开阈值U_leave这是模型的关键校准参数。可以通过查找行业报告估算出租车每小时的运营毛利润反推出一个合理的U_leave范围。在论文中应进行参数敏感性分析展示当U_leave在合理区间内变化时司机离开比例、系统平均收益等关键指标如何变化这能极大地增强模型的说服力。5. 结果分析与可视化呈现仿真跑起来后会输出海量数据。如何从中提炼出有价值的结论并用清晰的方式呈现在论文里是拿高分的关键。5.1 核心绩效指标计算仿真结束后我们需要计算并报告以下指标系统层面旅客平均等待时间旅客最长等待时间尾部效应出租车平均排队时间从进入蓄车池到接客系统吞吐量单位时间服务的旅客数司机层面出租车平均单位时间收益总收入/总在机场时间空载离开的出租车比例接到长途客和短途客的司机收益对比队列动态蓄车池队列长度的平均值、最大值、时间分布图旅客队列长度的类似统计5.2 可视化图表设计一图胜千言。在论文中至少要包含以下几类图时间序列图展示仿真过程中两个队列长度随时间的变化。这能直观看到拥堵的发生和消散。# 示例记录队列长度随时间的变化 # 在仿真过程中定期如每分钟记录 self.passenger_queue 和 self.taxi_queue 的长度 # 使用 matplotlib 绘制 import matplotlib.pyplot as plt plt.figure(figsize(12, 6)) plt.plot(time_points, taxi_queue_lengths, labelTaxi Queue) plt.plot(time_points, passenger_queue_lengths, labelPassenger Queue) plt.xlabel(Simulation Time (min)) plt.ylabel(Queue Length) plt.legend() plt.title(Dynamic of Queues Over Time) plt.grid(True) plt.show()分布直方图展示旅客等待时间、出租车收益的分布。这能揭示系统的公平性和稳定性。热力图或散点图展示司机决策结果。以“蓄车池队列长度”为X轴“旅客队列长度”为Y轴每个点代表一辆出租车做决策时的状态用颜色或形状区分其最终选择等待/离开。这张图能非常清晰地展示出决策边界。对比柱状图用于展示不同管理策略下的效果对比。例如对比“无管理”、“设置短途通道”、“动态信息屏提示预计等待时间”三种场景下的旅客平均等待时间和司机平均收益。5.3 管理策略模拟与建议这是赛题要求的最终输出。基于我们的模型我们可以模拟并量化评估几种常见策略“短途票”优先返回策略定义行程小于S0的为短途客。送短途客的出租车返回机场后可以进入一个优先队列。在我们的仿真中只需修改taxi_return逻辑让这类出租车插入蓄车池队列的较前位置而非队尾。然后对比实施前后司机接短途客的意愿、整体排队时间的变化。动态信息发布策略在蓄车池入口设立电子屏实时显示当前的预计排队时间基于当前队列长度和服务率计算。这改变了司机的信息集。在模型中我们可以让司机决策时使用的T_wait更接近真实值而不是基于固定服务率的简单估算或者直接使用信息屏提供的值。分析这一措施是否能减少“盲目排队”和“过早离开”平滑车流。预约调度策略进阶模拟一部分旅客通过App预约出租车。预约车辆可以不在蓄车池排队直接到指定地点接客。这相当于开辟了另一个服务通道能有效分流高峰压力。建模时需定义预约旅客的比例和预约车辆的调度规则。在论文中提出建议时一定要基于仿真数据。不要说“我们认为设置短途通道好”而要说“仿真结果表明在设定参数下引入短途通道能使司机平均收益提升X%旅客平均等待时间降低Y%但蓄车池平均队列长度会增加Z%。因此在高峰时段建议启用该策略以提升司机积极性在平峰时段可关闭以降低管理成本。”6. 论文写作要点与常见陷阱模型和程序做得好论文写砸了一切白费。数学建模竞赛本质上是一场“作文比赛”。6.1 论文结构骨架摘要重中之重用一段话浓缩全部精华。必须包含问题重述、建模思路用了什么方法、模型亮点、仿真主要结论、提出的管理建议。关键词准确。问题重述与分析不要抄题目要用自己的话分析问题的本质、难点、涉及的要素。明确列出要建立的模型和目标。模型假设与符号说明假设要合理、必要。符号表格要清晰上下标区分明确。模型建立与求解这是核心章节。按“总体框架→子模型推导收益计算、决策规则→仿真算法设计流程图文字描述→参数设置”的逻辑来写。公式要编号推导要有逻辑。仿真结果与分析先展示系统基本运行结果队列动态、决策边界图再展示核心指标。然后进行敏感性分析改变关键参数看结果稳定性。最后是策略模拟与对比。图表务必清晰有编号和标题在正文中要有引用和解读“如图1所示我们可以发现...”。模型的评价与推广客观评价自己模型的优点贴近实际、考虑...和缺点忽略了...、假设了...。提出可能的改进方向。将模型推广到类似场景如火车站、大型场馆的车辆调度。参考文献与附录参考文献格式要规范。核心程序代码可以放在附录但不宜过长放关键部分的伪代码或流程图更好。6.2 实战中踩过的坑与避坑指南坑1仿真时间不足未达到稳态。离散事件仿真需要一段“预热期”才能进入稳定状态。如果直接从0时刻开始统计初始的空载状态会拉低平均值。解决方法设置一个足够长的预热时间如仿真4小时前1小时的数据丢弃不统计或者从系统达到某种稳定条件如队列首次超过某个长度后再开始统计。坑2随机种子固定结果偶然性大。只跑一次仿真结果可能受随机数影响很大。解决方法对每种参数组合进行多次如50-100次独立重复仿真取各项指标的平均值和置信区间。在论文中要明确写出重复次数。坑3模型过于复杂无法验证。一开始就引入太多因素司机异质性、多上客点、交通拥堵导致模型参数巨多结果难以解释且无法验证正确性。解决方法从简到繁。先建立一个最简化的核心模型同质司机、单上客点、固定服务率把它调通得到可解释的基准结果。然后再逐步增加复杂性如加入短途客规则并分析新增因素带来的边际影响。坑4忽略单位一致性。时间用分钟距离用公里收益用元。计算单位时间收益时如果时间用小时收益用分钟就会出错。解决方法在符号说明表里就统一单位在代码和公式中始终保持一致计算前先检查量纲。坑5论文描述与程序实际逻辑不符。论文中说“司机每10秒决策一次”但程序里是“事件驱动决策”。这会被细心的评委发现。解决方法论文写作必须严格基于最终实现的代码逻辑。写论文时反复对照代码检查描述的准确性。最后再分享一个让论文脱颖而出的小技巧在结果分析部分除了展示宏观统计可以讲一两个“微观故事”。例如“我们追踪了一辆在晚高峰进入蓄车池的出租车ID1037它最初因为队伍长达120辆而选择离开但在我们模拟的动态信息提示策略下它看到预计等待时间为45分钟低于其阈值于是选择等待最终接到一位长途客获得了较高收益。” 这种具体案例能让你的分析更加生动和可信。数学建模竞赛的魅力就在于它用一个高度简化但内核深刻的模型去洞察和理解复杂的现实世界。机场出租车问题只是一个载体通过解决它你真正掌握的是系统思维、量化分析和用计算实验验证猜想的能力。这套方法放之许多管理优化问题而皆准。希望这篇超详细的拆解能为你打开一扇门不仅仅是解决一道赛题更是获得一种解决问题的强大工具。