tsp领域的问题, 并不都是tsp问题, 但是, tsp相关的算法一般都能解决, 只要你能为某一个充满个性的问题儿子找到他亲生的解决方案爸爸.
上一篇, 我们干净漂亮的用生成树算法解决了单一起点的配送分配问题. 这一篇, 我们面临了更严峻的挑战.
问题概述
- 随着业务的扩张, 你有了更多的仓库/取件点.
- 随着业务的扩张, 你开始接受很多友商的订单, 导致你的取派点的比例从1:300, 一直下降到接近1:3, 也就是说平均一个取件点只有3个目的地, 甚至于很多都是1个目的地的订单.
思考
刚刚看到这个问题的时候, 感觉上最小生成树已经不够用了, 那么怎么办? 我们想到了一个很直观的方法.
- 每个配送员都可以有一个路径. 新的订单分配给谁? 取决于这个订单加入之后, 谁的路径增加的值最小, 简单地说就是成本最小原则.
- 这基本上是一个克鲁斯卡尔算法, 多个订单进来, 每次都把开销最小(插入队列后形成的权重最小, 就是新增里程最小)的一个插入配送队列. 每次插入之后再更新一下这个被插入的队列(路径)对所有剩余订单的权重.
大约用了2天时间, 我实现了这个算法, 却悲哀的发现, 他虽然是一个多项式时间的算法, 但是开销达到了n的3次方, 虽然用强劲的机器, 或者引入并行运算就能解决, 但是, 这个算法还有一个关键的弱点: 不够简洁, 未来扩展会很困难, 所以, 我们应该继续寻找更好地算法. 此时, 我想到了参考友商的方案.
友商公开的方案
方案一, 二分图
- 但是, 很遗憾, 我们实际的数据逻辑是: 某个订单的起点和它的终点关系比较紧密, 而不同的订单的起点之间没有什么关系. 这个二分图抽象并无明显的业务实际含义, 相反, 它引入了一个不必要的复杂度.
方案二: 多边形
- 尺度问题, 只要a-a足够长, 那么顺轮的b-b订单就不会给他. 因为面积比下面的c-c-b-b大
- 方向问题, 订单的方向和顺路由很大的关系, 每个订单都要先取后送, 而计算面积的时候, 却没有考虑这个, 会导致错误的分配.
- 比如途中的b-b会分给a-a还是c-c呢? 从橙a出发, 明显不如橙c出发顺路. 但是面积不这么看, 并没有考虑,
- 由于路线方向的影响, 上面的aa线路只是少走了一条短边, 下面的cc线路会少走一条唱片
- 上面的线路是a取-a派-b取-b派, 而下面的线路是c取-b取-b派-c派
至此感觉我们走到了死胡同, 如果要突破, 我们需要更有力的工具, 各位大爷别急, 咱们下回分说