Minimum Fleet Problem「建议收藏」

Minimum Fleet Problem「建议收藏」本文为MITSenseableCityLaboratory2018年5月23号发表于Nature杂志Addressingtheminimumfleetprobleminon-demandurbanmobility论文的学习笔记。问题定义给定一批出行需求,在出行需求被严格满足且最大空驶时间不超过δ分钟约束下,找到…

大家好,又见面了,我是你们的朋友全栈君。

本文为MIT Senseable City Laboratory 2018年5月23号发表于Nature杂志Addressing the minimum fleet problem in on-demand urban mobility论文的学习笔记。

问题定义

给定一批出行需求,在出行需求被严格满足且最大空驶时间不超过δ分钟约束下,找到最小车队数

解决方案

总体思路:minimum fleet -> path cover -> maximum cardinality bipartite matching

轨迹处理

每条出行轨迹简化为四个信息:

  • 起点经纬度
  • 终点经纬度
  • 出发时刻
  • 到达时刻

根据上述信息进行以下几个方面的处理:

  • 地图匹配:使用OSM地图数据,以路口为节点,以道路为边,构建Graph,对起终点经纬度进行Map Matching,目的是抓到定位点100米内最近的路口上。
  • ETA:参数是每条道路的旅行时间;根据起点经纬度和终点经纬度规划路线,将途经道路的旅行时间加起来得到路线总时间,作为预测值;真值为轨迹到达时刻-轨迹出发时刻;优化目标是最小化平均相对偏差,即ME。具体实现时,有两个细节操作,一是路况的考虑,文章的具体做法是按照小时进行分组;二是匹配后相同起终点的轨迹做了清洗,去除了起终点在相同地方的轨迹、旅行时间过快和过慢的轨迹
  • 定义出行需求:一个需求用(起点经纬度、终点经纬度、出发时刻、预计送达时刻)四个信息进行描述

Vehicle-shareability Network与Path Cover

每一个节点代表一个出行需求(Trip),如果两个出行需求可以用同一辆车来满足,则在这两个节点之间添加一条边。判断节点i和节点j之间能不能添加边的条件如下:

节点i的预计送达时刻 + 节点i的终点位置到节点j的起点位置的预计旅行时间 <= 节点j的出发时刻 (保证用户实际需求不用等待)

节点j的出发时刻 – 节点i的预计送达时刻 <= 时间阈值(文章设置为15min,即车辆最大空驶时间为15min,保证车辆调度效率)

clipboard.png

按照上述方式搭建的网络,minimum fleet size问题就变成了path cover问题,我们从网络中找到一组路径对图进行互斥的覆盖后,路径的数量就是最小车队的数量。

二分图最大匹配

Vehicle-shareability网络是一个有向无环图(DAG),因此path cover可以转化为一个二分图。二分图的两组节点都是Trip,如果在Vehicle-shareability里邮编,则二分图里也有对应的边。这样的话,path cover问题就转变为 maximum cardinality bipartite matching问题。使用算法在二分图中找到最大匹配后,任选二分图中一个节点集合,其中未匹配的节点数就是最小车队数。详情可参见附录的资料。

Hopcroft-Karp算法

二分图匹配的关键思想是找到一个增广路径(augmenting path)。假如一个二分图当前已经进行了匹配(不是最大匹配),在该二分图中,仍然存在两个未进行匹配但是存在连通路径(路径可以由一条或多条边组成)的点,且在该连通路径上,已经选取的的边与未选取的边交替出现,称为增广路径。这个路径有一个重要性质,把路径上已经选取的边变成未选取,未选取的边变为已选取,匹配节点数增加了1。因此只要存在增广路径,通过取反操作,就能增大匹配数;当不存在增广路径时,我们就找到了最大匹配。

基于增广路径这个思路最简单的算法是Ford–Fulkerson algorithm,按照节点进行遍历,挨个节点寻找增广路径。寻找一个增广路径最坏需要遍历E条边,共有V个节点,因此复杂度为O(VE)。

Hopcroft-Karp算法的基本思路是:每一轮同时对于所有未匹配顶点的增广轨查找时,然后同时找出所有合法的增广轨(当然,这些增广轨的未匹配部分不允许重合),我们采用之前的增广轨取反法,分别用合适的顶点去匹配这些增广轨,每次匹配都可以给匹配数加1。直到再也找不到可匹配的增广轨,得到的即为最大匹配。Hopcroft-Karp算法的复杂度是O(V^0.5E)

Hopcroft-Karp算法的示意图如下:

// Hopcroft-Karp伪代码
/* 
 G = U ∪ V ∪ {NIL}
 where U and V are partition of graph and NIL is a special null vertex
*/
  
function BFS ()
    // 所有未匹配点的label设置为0,加入队列Q;所有匹配点的label设置为无穷大;伪节点的label设置为无穷大
    for each u in U
        if Pair_U[u] == NIL
            Dist[u] = 0  
            Enqueue(Q,u)
        else
            Dist[u] = ∞
    Dist[NIL] = ∞
    while Empty(Q) == false
        // 取出label最小的未匹配节点
        u = Dequeue(Q)
        if Dist[u] < Dist[NIL] 
            for each v in Adj[u]
                // 遍历u的邻接节点v
                if Dist[ Pair_V[v] ] == ∞
                    // 当邻接节点的匹配点的距离为无穷大
                    // ==>已匹配,更新Pair_V[v]节点的距离,这样不是无穷大,不会再被更新,保证了增广路径不相交
                    // ==>NIL,找到增广路径,更新NIL的距离,第一次遍历到的NIL的距离,决定了本轮查找的增广路最大长度
                    Dist[ Pair_V[v] ] = Dist[u] + 1
                    Enqueue(Q,Pair_V[v])
    // NIL的长度不为无穷大,说明有增广路径,否则没有
    return Dist[NIL] != ∞

function DFS (u)
    if u != NIL
        for each v in Adj[u]
            if Dist[ Pair_V[v] ] == Dist[u] + 1
                if DFS(Pair_V[v]) == true
                    Pair_V[v] = u
                    Pair_U[u] = v
                    return true
        Dist[u] = ∞
        return false
    return true

function Hopcroft-Karp
    for each u in U
        Pair_U[u] = NIL
    for each v in V
        Pair_V[v] = NIL
    matching = 0
    while BFS() == true
        for each u in U
            if Pair_U[u] == NIL
                if DFS(u) == true
                    matching = matching + 1
    return matching

应用

根据海量历史请求,计算得到了最小车队数量Nmin。在线使用时,令N=1.2Nmin。然后对于实时发单的出行需求,使用以下两种模型进行派单:

On-the-fly:来一单,派一单,选择标准是使用户从发单到上车这段等待的时间最短

Batch:压单1min,对这一批运单构建司机和运单的有权二分图,边权重为用户发单到上车的等待时间,最大值设置为6min,然后使用maximum matching(如KM算法)求解

从上图可以看出,使用压单1min、最大等待时间6min这套参数的Batch派单模式,需求满足率平均可以达到92%,远远超过on-the-fly的模式。

附录

Matching问题:https://en.wikipedia.org/wiki…

Path Cover与二分图:https://stackoverflow.com/que…

二分图匹配算法:http://blog.sina.com.cn/s/blo…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/135268.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 移动apn接入点哪个快(移动哪个接入点网速快)

    9条解答1.中国移动4g接入点最快我不同意,中国LTE才是最快的,就是流量怕你不够,名称:LTE,APN:lte(小写的),APN协议漫游协议lpv4,我的达到了2.5~3M/S,骗你出家2.4g网速很慢,求助apn设置方法您好!您先进入手机的接入点设置–新建apn接入点–名称乱填,apn:cmtds–保存保存之后,选择自己刚刚设置的接入点,然后您就会发现您自己的手机4G网络的速度很快了,…

    2022年4月12日
    465
  • c++读写锁实现_设计模式PDF

    c++读写锁实现_设计模式PDFC++读写锁设计允许读数据同时进行,但与写数据是互斥的存在,只有读数据操作所有完成后释放锁才允许写。反之亦成立。自旋式读写锁,减轻使用者的释放锁的烦恼,当自旋读写锁超出作用域则会自动释放锁。

    2022年8月12日
    6
  • webpack图片压缩_webpack的cdn

    webpack图片压缩_webpack的cdn图片处理url-loader(webpack5之前的处理方式)在项目开发中,我们时长会需要使用到图片,比如在img文件夹中有图片test1.png,然后在normal.css中会引用到图片body

    2022年7月30日
    5
  • Apache日志分析_shell命令行

    Apache日志分析_shell命令行

    2021年10月8日
    33
  • C语言实现PID算法:位置式PID和增量式PID[通俗易懂]

    原创者微信公众号PID算法可以说是在自动控制原理中比较经典的一套算法,在现实生活中应用的比较广泛。大学参加过电子竞赛的朋友都应该玩过电机(或者说循迹小车),我们要控制电机按照设定的速度运转,PID控制在其中起到了关键的作用。说来惭愧,大学这门课程学的不咋滴,老师讲的课基本没听进去过。直到后面接触竞赛,算是对PID有了很基础的一点点认识,直到现在工作实际应用的…

    2022年4月11日
    113
  • mysql服务器失败1396_Mysql ERROR 1396 (HY000) 错误的解决办法

    mysql服务器失败1396_Mysql ERROR 1396 (HY000) 错误的解决办法建立用户的时候报告这个错误:ERROR1396(HY000):OperationCREATEUSERfailedfor‘abc’@’localhost’原因是mysql中已经有了这个用户,从mysql.user中直接删除delete,然后刷新权限FLUSHPRIVILEGES,再建用户就不会有这个问题了。如果是dropuser的话,mysql内部会自动刷新一下,那么再建也不会…

    2022年8月12日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号