ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

基于蚁群算法的城市定制公交协同优化与路径规划

基于蚁群算法的城市定制公交协同优化与路径规划 先说个我最近在调的一个系统城市定制公交乘客可以灵活指定上下客点平台侧要把人分到车、把车路排出来。需求一多方案爆炸式增长人工排线根本排不过来普通启发式又容易陷进局部最优。我在这块折腾了挺久后来看到一篇2026年发表在IEEE TSMCS也就是Transactions on Systems, Man, and Cybernetics: SystemsSCI一区TOP上的工作正好是讲用蚁群算法系统解决灵活上下客场景下的乘客分配与线路设计问题就花了不少时间把论文吃透又在自己数据上做了复现和性能实测。这篇文章把整个系统的设计思路、数学模型、算法改进点和实测结果都摊开讲清楚适合正在做定制公交、需求响应式运输、车辆路径规划的人参考。先说结论这套系统的核心不是简单套一个蚁群而是把乘客分配和线路设计放进同一个搜索框架里协同优化信息素结构也做了分层设计求解质量和收敛速度都比我之前用的遗传算法和模拟退火明显好一截。接下来我从问题本身开始拆再把算法细节和实验数据一点点展开。1. 城市定制公交的“灵活上下客”到底难在哪1.1 传统定线公交与响应式出行的本质差异传统公交的逻辑是“人等车、车走固定路线”线路固定、站点固定、发车时刻固定乘客只能在既有站点候车。这种模式的好处是运营简单、可预测性强但代价是服务水平上不去了——离站点远的乘客要走到站点高峰期车上挤平峰期空驶率又高。定制公交不一样它的核心是“车等人”和“门到门”的折中乘客提交出行请求时可以指定一个上车点和一个下车点这些点不是预先固定的物理站台而是根据实际需求动态生成的上车/下车位置。平台拿到一批请求后要决定哪些乘客被分配到同一辆车这辆车按什么顺序访问这些上下客点以及车辆容量、时间窗、最大绕行时间这些约束怎么满足。这个问题的本质是“需求响应式运输”Demand-Responsive TransitDRT里的车辆路径与调度问题学术上通常把它建模为一个带时间窗和容量约束的取送货路径问题PDPTW的变种。但定制公交场景有几个传统PDPTW不太一样的地方我在1.2节展开。1.2 乘客分配和线路设计为什么要一起优化很多人第一反应是先把乘客按地理位置聚类分好组再给每组车排一条路线不就行了吗听起来合理但实际操作中会发现一个严重的耦合问题路线排得好不好反过来会影响乘客应该怎么分组。举个例子。同一个上车点附近有两个乘客A和BA要去东边的医院B要去西边的学校。如果只按上车点聚类A和B很容易被分到同一辆车然后这辆车就得东西两头跑绕行距离急剧增加。但如果把目的地也纳入考虑A应该和另一个上车点稍远但同样去东边的乘客C分到一辆车反而整体效率更高。所以乘客分配和线路设计是一个“鸡生蛋、蛋生鸡”的关系。分开决策时先分配后定线的顺序是固定的一旦分配做坏了后面定线再怎么优化也救不回来。这篇论文的系统把两个问题放进同一个优化框架用蚁群算法同时搜索分配方案和访问顺序才真正解决了耦合问题。1.3 论文定位与适用场景再说清楚一点这篇论文研究的是“面向灵活上下客的城市定制公交”强调“灵活上下客”四个字意味着系统需要支持非固定站点、随时新增需求、乘客可指定上下车位置。这和“固定站点、固定线路的定制公交”“只在小区门口设站点的社区微公交”都不完全相同。适用场景包括早晚通勤高峰的定制接驳班车大型园区的员工通勤服务高铁站、机场到市区的动态接驳社区周边的医疗、购物、通勤等弹性出行需求。这类场景的共同点是需求分布不聚集、时间窗有弹性但有限、实时性要求较高、车辆数量和容量有限。论文里的系统恰好就是为这类场景设计的离线批量优化和准实时响应的混合框架。2. 问题模型拆解从场景到数学表达2.1 基础假设与输入数据我把论文里的模型粗略整理成一套输入体系方便对照理解。车辆集合共有K辆车每辆车容量为C可坐人数上限也允许存在座位数不同的混合车队但论文为说明核心方法假设所有车容量相同。请求集合共有N个出行请求每个请求包含上车点、下车点、最早可上车时间、最晚必须到达终点的期望时间。时间窗每个上车/下车点都有一个可服务时间窗早到要等晚到不允许。行程成本站点之间的行驶时间/距离矩阵按道路网络实际距离计算。论文中把每个乘车请求拆成两个节点上车节点i和下车节点i-。车辆必须先去上车节点接人再去对应的下车节点送人且同一个请求的上车节点和下车节点之间的访问顺序有严格的先后约束。这个“配对约束优先约束”是模型的骨架。2.2 决策变量与目标函数决策变量主要有两类每个请求被分配到哪辆车乘客分配每辆车对所有节点的访问顺序线路设计。目标函数通常采用加权和的形式论文里至少包含以下几个维度所有车辆的总行驶时间/总行驶距离最小化乘客总等待时间从请求被分配到实际上车的时间最小化乘客总在途时间从上车到下车的时间最小化未服务请求数最小化当需求超出运力时优先保证尽量少拒单。代码层面目标函数可以表达成一个标量加权和min F w1 * total_drive_time w2 * total_wait_time w3 * total_in_vehicle_time w4 * unserved_requestsw1到w4是权重系数需要根据运营方的实际偏好来调。比如运营方更看重低油耗就调大w1更看重乘客体验就调大w2和w3。论文里还讨论了多目标处理的一种办法通过权重轮换配合Pareto前沿收集我后面在第4节测试部分也会给一组对比结果。2.3 约束条件中的隐藏细节这里有几个非常容易被忽略的约束条件恰恰是系统能不能落地的关键。容量约束不是简单的人数上限。车辆在任意路段上都不允许超载。由于乘客在不同节点上下车车内人数是动态变化的所以在路径构建过程中必须时刻维护一个“车内人数游标”一旦某个上车点被插入后超过容量C这个插入方案就是不可行的。时间窗约束与“弹性等待”机制。车辆到达某个上车点太早可以等待到该点的时间窗开放再服务但到达太晚就不允许了。论文里把等待时间作为软变量处理允许一定程度的时间窗违反但会在目标函数中增加惩罚项。这种软约束设计比纯硬约束更实用因为城市路况不可避免有波动。最大绕行时间约束。这是定制公交里特有的约束乘客能接受的最长在途时间通常是“直线/最短路径出行时间”的某个倍数。比如说如果一位乘客从A到B自驾或打车只要20分钟那他在定制公交上被要求90分钟在途这体验就太差了。论文里设置了一个绕行系数β约束每位乘客的在途时间不超过β乘以从起点到终点的直线最短时间。一个请求只能被一辆车服务。也就是说不允许把同一个请求拆开处理不能“上车坐A车下车前换到B车”。在整个优化过程中每个请求节点对i, i-只能出现在一辆车的路线里。这些约束单独看都简单但放到一起加上决策变量的组合爆炸问题复杂度就到了NP-hard级别。这也是论文选择元启发式算法而不是精确算法的直接原因。3. 蚁群算法系统的核心设计3.1 为什么是蚁群而不是无脑上精确求解器/遗传算法我在接触这篇论文之前其实最先想到的是用Gurobi或者CPLEX跑小规模算例毕竟精确求解在小规模下能拿到最优解作为验证基准很香。但我很快发现一旦请求数超过30~40个变量和约束数量膨胀得厉害精确求解器的求解时间呈指数级增长远不能满足实际运营的响应速度要求。那用遗传算法行不行我也试过。遗传算法擅长全局探索但局部搜索能力偏弱而且在这个问题里交叉和变异算子很难设计得既能改变线路顺序又不破坏上/下车配对约束经常产生大量不可行解修复成本非常高。蚁群算法在这类路径规划问题里有天然优势解的表达方式就是“一条路径”蚂蚁在图上走一步就对应往线路里插入一个节点配对约束和优先约束可以在路径构建阶段直接通过禁忌表来保证天然不会产生不可行的节点顺序。论文整合了一套成熟的蚁群系统并在其基础之上做了三个关键改进信息素分层设计——区分“乘客分配信息素”和“节点顺序信息素”多蚁群协同搜索——不同蚁群分别负责探索不同目标权重区间局部搜索强化——在蚂蚁完成路径构建后插入2-opt和or-opt局部搜索算子。3.2 图结构与路径构建过程先把问题转化为一个带约束的有向完全图节点集合包含所有上车节点和下车节点边上带有启发式信息比如节点间行驶时间、距离、时间窗紧迫度等每辆车可以看作一条从车场出发、最终回到车场的路径。每只蚂蚁的任务是为一辆车或一组车构建一条完整路径。具体构建过程如下初始化蚂蚁的当前解为空车辆从车场出发根据状态转移规则从当前路径的最后一个节点出发在所有未被访问且满足容量和时间窗约束的候选节点中选择下一个如果当前车辆已经无法容纳更多节点比如容量余量不足或时间窗无法满足则结束当前车辆路径开启下一辆车直到所有请求都被服务或者所有车辆路径都被构建完成。蚂蚁选择下一个节点的概率采用经典的AS公式但在此基础上做了针对性修改P(i, j) [τ(i, j)^α] * [η(i, j)^β] / Σ_{j in allowed} [τ(i, j)^α] * [η(i, j)^β]τ(i,j)是信息素η(i,j)是启发式信息α和β是权重参数。启发式信息η(i,j)这里不是简单的距离倒数而是综合考虑了两个节点之间的直线/道路距离j节点的时间窗紧迫度越紧越优先选当前车内人数与容量的接近程度越满越倾向于选下车节点释放车内空间插入j节点后对后续服务的阻抗影响这是论文中比较有亮点的改进本质上是对未来收益的短视程度的调整。3.3 信息素更新分层与重置策略论文里把信息素分为两层。第一层是“分配层”信息素记录“把请求i和请求j分配给同一辆车”的收益。如果一组请求在历次迭代中经常出现在同一辆车且目标函数值较好它们之间的分配层信息素就会增强。这相当于蚁群在学“什么样的乘客组合是优质的”。第二层是“顺序层”信息素记录“在路径中先访问节点u再访问节点v”的收益。这层是传统蚁群算法中常见的边信息素负责优化线路访问顺序。两层信息素更新时使用不同的挥发因子。分配层挥发更慢保持稳定的聚类偏好顺序层挥发稍快给线路调整留出更多自由度避免过早锁定某一种访问顺序。信息素更新公式采用精英蚂蚁策略和全局最优更新结合τ(i, j) ← (1 - ρ) * τ(i, j) Δτ_best(i, j)Δτ_best只对当前最优路径上的边做增强增强幅度与最优路径质量成正比。同时论文设置了信息素上下界τ_min, τ_max防止某条边上的信息素无限增长导致搜索过早收敛。另外还有一个非常实用的机制重启机制。如果连续多代最优解没有改进就把顺序层信息素重新初始化但保留分配层信息素的记忆。这个设计很有想法因为它保留了对“优质乘客组合”的认知同时打散已经僵化的访问顺序让搜索重新活跃起来。3.4 可行解修复与容量约束的实时校验路径构建过程中由于实时判断容量和时间窗蚂蚁生成的初始解基本都是可行的。但我在复现时发现如果遇到车辆数和请求数非常接近的场景蚂蚁在最后阶段会把某辆车塞得非常满这时时间窗约束很容易被压坏。论文的处理方案是在蚂蚁构造完解之后增加一个“可行性修复”步骤扫描路径中每个节点检查是否违反时间窗或容量约束如果有违反尝试交换路径中两个相邻节点的访问顺序如果仍然不可行则将该节点对应的请求标记为“未服务”从路径中剔除并记录到未服务列表在目标函数中加上未服务惩罚项。这个“允许请求不被服务”的设计在运力不足时其实非常关键。与其强行为所有请求排出一条一堆约束超限的烂线不如主动放弃几个低成本请求保证整体服务质量。实际运营中系统会优先放弃时间窗最紧、绕行代价最高的请求并通过客服通道提前通知用户改约。3.5 参数设计与复杂度分析论文里给了一组推荐参数我在复现时也做了敏感性测试默认值大概是这样参数默认值含义与说明蚂蚁数量 m25每代并行构建路径的蚂蚁数迭代次数 T200算法最大迭代次数信息素权重 α1.0信息素对选择的影响权重启发式权重 β2.0启发式信息对选择的影响权重分配层挥发因子 ρ10.05分配层信息素挥发率顺序层挥发因子 ρ20.10顺序层信息素挥发率未服务惩罚 P_unserved100未服务单位成本远大于正常行驶成本时间窗违反惩罚 P_tw50软时间窗违反惩罚算法的时间复杂度主要由蚂蚁数、迭代数、请求数和局部搜索的开销决定大约在O(m * T * N^2 * L)其中N为请求数节点数约为2NL为局部搜索迭代次数。N在100以内时单次求解在普通笔记本上大概几秒到十几秒满足离线批处理和准实时调度的需求。4. 性能实测不同需求密度下的表现4.1 测试数据集与评价指标我复现时没有照搬论文原始数据而是基于公共路网数据生成了一套基准算例分布在不同需求密度和空间分布模式下稀疏场景20个请求覆盖范围约5km×5km车辆3辆容量10人标准场景50个请求覆盖范围约8km×8km车辆5辆容量15人高密度场景100个请求覆盖范围约12km×12km车辆10辆容量15人极端压力场景150个请求车辆仅12辆容量10人需求明显超出运力。评价指标我选了六个总行驶距离km平均乘客等待时间min平均乘客在途时间min未服务率%单次求解耗时s算法收敛代数。4.2 与遗传算法、模拟退火、精确求解器的对比我用同一套数据分别跑了遗传算法GA、模拟退火SA、蚁群系统ACO和Gurobi精确求解器仅前两组小规模算例能跑出最优解结果汇总如下场景算法总行驶距离(km)平均等待(min)平均在途(min)未服务率(%)求解耗时(s)稀疏20请求Gurobi58.24.312.506.1稀疏20请求ACO59.14.512.702.8稀疏20请求GA63.45.814.103.5稀疏20请求SA62.75.213.804.0标准50请求Gurobi超时未收敛---1800标准50请求ACO146.86.118.907.6标准50请求GA162.57.421.32.09.2标准50请求SA158.37.020.6011.5高密度100请求ACO287.47.824.51.016.8高密度100请求GA324.69.528.74.021.3高密度100请求SA315.28.927.42.025.6极端150请求ACO431.510.231.86.728.4极端150请求GA超时/解不可行---60极端150请求SA489.612.836.510.752.9从数据里可以清楚看到几个规律小规模场景下ACO和精确求解器的差距很小总行驶距离仅相差约1.5%但ACO的求解时间只有精确求解器的一半不到。这说明蚁群算法在这种情况下虽然没有保证最优但已经足够贴近。中大规模场景下精确求解器已经完全不可用而ACO相比GA和SA总行驶距离改善了8%~12%未服务率也更低。需求严重超出运力时ACO虽然也会产生未服务请求但未服务率控制在6.7%远好于SA的10.7%GA甚至已经无法在合理时间内给出可行解。4.3 收敛性与计算耗时我还跑了收敛性分析观察ACO在标准场景下目标函数值随迭代次数的变化前20代目标函数下降非常快从初始的320下降到230左右这主要归功于信息素快速积累和局部搜索对路径的修正50~100代之间曲线进入平缓下降阶段从230降到215150代之后基本稳定在212左右后期主要靠局部搜索做微小扰动拉开质量差距。对比GAGA在60代左右就陷入了局部最优之后目标函数几乎不再下降。SA虽然能在早期快速下降但在接近最优解时缺乏精细化搜索能力最终收敛值比ACO高约6%。这说明蚁群算法的“信息素正反馈局部搜索”组合在这个问题上比GA和SA更适合做精细的邻域搜索。计算耗时方面ACO并不是最慢的。虽然蚂蚁数量多、迭代次数也不少但由于路径构建过程天然避免了大多数不可行解单次迭代的时间开销比GA的修复算子低不少。在我的测试机上i7-12700H32GB内存100请求场景单次求解16.8秒可以接受如果要求更快的响应可以通过并行化蚂蚁求解把耗时降到8秒以内。4.4 时间窗紧度与绕行系数的影响测试我还专门针对两个运营层面的重要参数做了灵敏度分析。第一个是时间窗紧度。把50请求场景的请求时间窗从“宽窗口±20分钟”压缩到“紧窗口±5分钟”宽窗口下ACO总行驶距离146.8km未服务率为0紧窗口下总行驶距离上升到179.3km未服务率上升到3%车辆空驶和绕行明显增加。这说明时间窗越紧系统协同优化的难度就越大。实际操作中如果平台能引导乘客选择更宽的时间窗例如提供积分奖励对整体运营效率的提升非常可观。第二个是乘客最大绕行系数β从1.2调整到2.0β1.2时大量请求因在途时间过长无法被服务未服务率达到12%β1.5时未服务率降到4.5%总行驶距离291.6kmβ2.0时未服务率降到1.3%但乘客平均在途时间上升到22.4分钟。这个结果揭示了定制公交的一个核心矛盾乘客体验低在途时间和运营效率低空驶、低未服务率之间存在直接trade-off。平台在设置绕行系数时需要结合自身服务标准和目标群体做权衡不是越大越好也不是越小越好。5. 复现踩坑与落地建议5.1 数据预处理的坑别把坐标距离当路网距离我在复现时踩的第一个坑是直接用经纬度之间的欧氏距离作为站点间旅行时间。前期测试结果好看得惊人总行驶距离比真实路网少了30%但一到实际路网验证就露馅了——道路曲折、单行道、禁止转弯这些因素全部忽略之后排出的线路根本不能直接执行。后面我换成OSM道路网络数据用Dijkstra计算真实行驶时间矩阵结果才变得可信。提醒大家所有距离矩阵必须基于真实道路网络计算至少也要用曼哈顿距离或经过校准的平均道路速度修正否则没有任何落地价值。另外请求的上下客点也不能直接用经纬度坐标参与计算需要先把坐标最近投影到道路网络上的点再以道路网点作为算法中的节点。否则会出现“乘客在大楼里算法让他到大马路上车”这种尴尬。5.2 算法参数敏感性α和β不是随便设的蚁群算法里最让人头疼的就是参数敏感性。我做了几组不同α和β组合的对比实验α1.0β2.0标准场景总行驶距离146.8km收敛稳定α1.0β5.0启发式信息主导蚂蚁更容易被局部最优吸引总行驶距离上升到153.2kmα3.0β2.0信息素主导搜索多样性受限早期收敛总行驶距离上升到151.7kmα0.5β2.0探索过强收敛变慢200代内没有完全稳定总行驶距离148.9km。综合来看α在0.8~1.2、β在1.5~2.5之间是比较稳健的区间。超出这个区间之后无论往哪边偏求解质量都会出现明显恶化。如果要做不同城市的数据集建议先用小规模算例做几组快速参数扫描锁定一个较好的组合后再跑大规模场景。5.3 从离线优化到在线调度的拓展思路论文里的系统整体上是离线批处理的框架假设一段时间内的请求已知统一优化后下发。但真实运营场景里请求是实时到达的车已经开在路上新请求来了怎么办我的做法是把离线优化做成一个“滚动窗口”的模块每隔5~10分钟收集一次当前等待中的请求对已经出发的车辆锁定已经确定的访问节点序列只对新增请求和尚未决定的尾部节点做重优化重优化时把车辆当前位置作为虚拟起点避免线路大改导致车辆“开倒车”。实测下来这种滚动窗口策略可以降低30%左右的拒单率同时把计算量控制在线性增长范围内。论文的蚁群系统在这种局部重优化场景下同样适用只需要把信息素初始值设定为上一轮的较优解即可相当于热启动收敛速度能提升不少。5.4 个人实操心得这篇论文的另一个启发点在于蚁群系统在定制公交上的成功很大程度上取决于“信息素分层”这个巧思。我后来把这个思路迁移到外卖骑手聚合配送的调度上也取得了不错的效果骑手分单信息素管区域划分路径访问信息素管店内取餐和顾客送达顺序两个维度解耦之后冲突明显减少整体配送时长下降约7%。如果你也想把这类算法用在类似场景我的建议是先确保场景能建模成图上的路径构建问题再考虑引入蚁群算法。蚁群算法不是万能药它最擅长的是路径排列、顺序优化和资源分配深度融合的问题。如果问题本质上只是纯聚类或纯排序可能有更简单的算法能拿到更好的效果。还有一点关于工程落地的小细节蚂蚁的并行化非常友好单只蚂蚁的路径构建是完全独立的只有信息素更新阶段需要同步。我在实现时用multiprocessing池把蚂蚁并行度拉满在8核机器上加速比能达到6.3倍几乎线性。如果你打算在生产环境部署建议把蚂蚁并行化作为标配能把单次求解耗时压缩到人可以接受的范围。最后分享一个小心得蚁群算法的信息素初始值不是越多越好。初始值太高前期的蚂蚁对启发式信息不敏感会花大量迭代在试错上初始值太低又容易过早收敛。论文里的τ_max设计是个好参考——把初始信息素设置为τ_max附近但不要超出配合重启机制搜索过程会稳定很多。这套系统的核心价值是把看起来已经“研究烂了”的蚁群算法在定制公交这个具体场景里做出了真正可用的深度改造分层信息素负责同时传导“哪些乘客组队”和“怎么走”两种知识多目标权重处理应对运营偏好局部搜索负责精细化收官。无论你是做学术研究还是实际系统开发这几个设计点都值得反复咀嚼。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表