十年前我刚入行时,外卖小哥们还在用对讲机抢单。当时最"智能"的系统,就是在APP上显示方圆3公里内的订单列表,骑手们像抢红包一样疯狂点击屏幕。我亲眼见过一个骑手为了抢单价高的订单,把手机屏幕都戳裂了。这种抢单模式最大的问题是:懂技术的骑手会写脚本自动抢单,新手经常抢不到好单;更糟的是,所有人都盯着写字楼的高价单,居民区的订单经常超时。
后来出现了人工调度室,每个商圈配2-3个调度员,他们面前放着六块显示屏:订单地图、骑手定位、商家出餐监控... ... 有经验的调度员能记住50个骑手的习惯,比如张师傅熟悉CBD区域,李师傅的电动车续航强。但2016年美团日订单量突破1000万单时,这种模式彻底崩了——调度员平均每2秒就要做一次派单决策,人脑根本跟不上。
转折点出现在2017年,我们团队接到的死命令是:用算法替代90%的人工调度。当时最头疼的是冷启动问题——没有历史数据怎么训练模型?我们想了个土办法:先让算法模仿资深调度员的决策,就像AlphaGo先学人类棋谱。上线第一个月,系统派单的准时率就比人工调度高出8%,这个数字现在看起来可能不起眼,但在当时让整个团队看到了曙光。
早期的智能调度系统本质上是规则引擎,我们把老师傅的经验写成300多条IF-THEN规则。比如:
python复制if 订单距离>5km and 当前时间>14:00:
分配给出勤时间<4小时的电瓶车骑手
elif 商家出餐慢 and 用户评分>4.5:
分配给耐心值>80分的骑手
这种方法的优势是解释性强,骑手能理解为什么派单给他。但很快就遇到瓶颈:规则之间经常打架,修改一个参数可能引发连锁反应。最严重的一次,因为新增了"雨天优先派给穿雨衣的骑手"这条规则,导致晴天时雨衣骑手接不到单。
2017年我们开始构建实时预测体系,这个阶段的关键突破是对三类时间的精准预测:
这个阶段我们踩过最大的坑是特征穿越——不小心把"实际送达时间"作为特征训练模型,导致线上效果远超线下测试。后来我们建立了严格的特征版本管理机制,就像数据科学的"版本控制"。
现在的调度系统是三层级联模型:
最让我自豪的是动态改派算法:当骑手A距离用户还剩500米但遇到交通管制时,系统会让200米外的骑手B接应。这就像下棋时的"弃子战术",虽然改派成本很高,但避免了超时赔付。实测这个策略让超时率下降了23%,而改派率只增加了5%。
早期我们把订单分配简化为二分图匹配问题:左边是订单节点,右边是骑手节点,边的权重是预计配送时长。这种方法计算速度快(能在100ms内处理1000个订单),但存在明显缺陷——没有考虑骑手接单后的状态变化。
现在的模型是时空状态网络:
我们对比过三种主流算法:
| 算法类型 | 计算速度 | 优化效果 | 适用场景 |
|---|---|---|---|
| 贪心算法 | <100ms | 局部最优 | 低峰时段 |
| 遗传算法 | 2-5s | 全局次优 | 新骑手培训 |
| 强化学习 | 300-800ms | 动态最优 | 高峰时段 |
实际采用混合策略:平峰期用改进的Dijkstra算法,高峰期启动分布式强化学习集群。这里有个工程细节:算法模块要用C++编写,Python层只做策略调度,这样能节省40%的计算时间。
最难的其实不是算法实现,而是定义什么是"最优"。我们花了三个月做AB测试,最终确定的多目标权重:
这个公式会动态调整,比如下雨天会把骑手安全权重从5%提升到15%。最近我们还在试验后悔值模型,不仅考虑当前决策的最优性,还评估如果5分钟后有新订单会不会后悔现在的分配。
调度系统最怕遇到雪崩效应。我们的解决方案是:
去年双十一当天,某个云服务商宕机了17分钟,这套机制让我们保持了99.99%的SLA。
完全依赖算法是不现实的,我们设计了人机协同机制:
有个有趣的发现:人类调度员在处理"情绪化用户"订单时,效果比算法好15%。现在我们正在训练情感分析模型来弥补这个差距。
最烧钱也最值钱的资产是数字孪生系统,它包含:
每次算法迭代都要先在仿真系统跑通7天数据,这个习惯让我们避免了三次重大事故。有次新算法在测试时导致"骑手总骑行距离增加30%",后来发现是因为过度优化单均时长,让骑手频繁短途折返。