1、道路网上最短路径算法综述道路网上最短路径算法综述张波良1 张瑞昌1 关佶红2【摘 要】摘 要 在道路网上计算两点之间的最短路径是图论算法的众多实际应用之一。经典的Dijkstra算法在大规模图上过于缓慢。过去十年间,这个经典问题在道路网上取得了重大突破,目前已知最快算法的运行效率比Dijkstra算法快了百万倍。这些算法都对道路网数据进行预处理,产生一定的辅助信息以加速查询,其中目标向导方法和层次化方法是两类典型方法。一些算法的实验性能良好,但缺乏理论支撑。这是因为难以用数学语言严格地刻画道路网的特性。因此,如何弥合理论与实践的差距是此问题面临的主要挑战。【期刊名称】计算机应用与软件【年(卷)
2、,期】2014(000)010【总页数】9【关键词】关键词 最短路径 道路网 层次化0 引 言给定起始点与目标点,在道路网中计算最短路径是一个常见问题。许多人外出旅游、计划驾车路线时经常涉及此类问题。生活中也有很多应用需要处理大量的最短路径查询,譬如物流规划,交通模拟等。就目前而言,商业的解决方案往往效率低下或者查询结果不够精确。收集道路网数据的技术已日趋成熟,公开的道路网数据规模也随之增大,目前已知的最大道路网美国道路网1,涵盖了2 300多万个节点与5 800多万条边。一方面,使用简单朴素的算法会使得查询速度非常缓慢。对于提供最短路查询的服务来说,客户的响应时间会过长,而服务供应商则需要投
3、入更多的计算资源来处理查询请求。另一方面,使用启发式的搜索算法会导致查询结果不精确。对客户而言,这可能意味着浪费时间与金钱;对服务供应商而言,查询效率与次优路径的选择往往顾此失彼,不可兼得。有趣的是,追求次优路径未必能保证高效的查询效率,反之也一样。鉴于这些原因,如何在道路网上高效而精确地计算最短路径成为了近年来一个热点课题,引起了学术界的广泛兴趣。道路网很容易用图来表示,顶点表示枢纽节点,边表示路段,连接两个枢纽节点。每条边被赋予权重,表示经过该路段的代价。这里代价不仅仅可以表示路段长度、行程时间估计,还可以表示通行费用、能源消耗、景点的吸引力等,还可以是各种度量的组合。出于习惯,我们一直使
4、用术语最短路径来表达最小代价路径的意思。可能的话,我们不仅希望计算出最短路径长度,还能够得到路径的具体表示。早在1959年Dijkstra就给出了一个单源最短路径的算法2,该算法需要O(m+n)次优先队列操作,这里代表边数,代表顶点数。在大规模道路网中计算两点之间的最短路径时,Dijkstra算法过于缓慢。以下几个方面提出了改进建议:首先,Dijkstra算法有计算冗余,因为它从顶点S出发不仅计算出到点t的最短路径,还算出了到所有点vV的最短路径。针对这一点,只需在Dijkstra算法上做出小小改动,即在s-t的最短路径被发现后就停止算法。即使这样,改进算法仍有不少冗余,因为所有距离比点t更近
5、点的最短路径也都计算出来了。其次,许多应用需要在同一个道路网上进行大量的-最短路径查询。这种情况下,花费一定时间对图数据进行预处理是值得的,因为所有的后续查询都会利用预处理产生的辅助数据,以有效地减少算法搜索空间,提高查询速度。再者,本文仅仅讨论道路网,而非一般图,道路网有一些特定的性质。1)道路网是稀疏图。在道路网中某个节点的度数超过5是非常罕见的。2)道路网近乎是平面图。它不是严格意义上的平面图是因为桥梁和隧道在空间上与其他路段存在交叉。此外,各个枢纽节点的布局通常是固定的,这意味着我们可以利用枢纽节点的地理坐标信息。3)道路网呈现出层次化特性。高速公路比城镇街道更“重要”,这种重要性体现
6、在通过高速公路的最短路径要多于通过城镇街道的最短路径。利用以上观察结果设计加速算法,可以使得道路网上的查询速度比Dijkstra算法提高好几个数量级。同时,理想的加速算法还应该满足以下要求: 1)查询时间要尽可能快。2)查询结果必须精确,路径应该是最优的。3)算法应与图的规模无关,不能只对较长或较短的路径进行优化。4)算法若使用预处理,预处理算法能够有效地处理大规模图数据。5)预处理产生的辅助数据的空间开销要适度。6)算法应该支持某些边权重的更新(如交通堵塞导致行程时间增加)。7)算法能够应用于依赖时间的网络(如路段行程时间取决于出发时间)。通常这些要求互相矛盾。快速的查询时间往往要求更多的预
7、处理时间和更大的空间开销。因此,该问题面临的一个挑战是找到能够平衡所有需求的算法。1 问题定义与经典算法1.1 最短路径定义我们用有向图G=(V,E)表示道路网,其中顶点集V大小为n,边集EVV大小为m(如无特殊说明,本文总是使用m表示边数,n表示顶点数)。代价函数W:E+0为每条边赋予非负权重w(u,v)。一条从u1到uk的路径P是一组边序列(u1,u2),(u2,u3),(uk-1,uk),可以简写为u1,u2,,uk,其中u1和uk为路径的端点,其余的顶点ui(2ik-1)称为内部顶点。路径P的长度w(P)为P包含边的权重之和,即路径P*=s,,t是一条最短路径当且仅当不存在s-t路径P
8、使得w(P)lt;w(P*)。在图G中,从s到t的距离dG(s,t)定义为s-t最短路径的长度,如果不存在从s到t的路径则dG(s,t)=,若图G在上下文中意义明确,可简写成d(s,t)。在图论中,最短路径是一个经典问题,它有以下几个变种:(1)两点之间最短路径 给定源点sV和目标点tV,计算从s到t的最短路径。(2)单源最短路径 给定源点sV,计算s到所有顶点vV的最短路径。(3)多对多最短路径 给定顶点集合S,TV,计算每个点对(s,t)ST直接的最短路径。(4)全源最短路径 多对多最短路径的一种特例,即S=T=V。本文仅仅讨论第一种情况:两点之间的最短路径。1.2 Dijkstra算法D
9、ijkstra算法为图中每个顶点u维护一个临时距离d(u)与当前状态S(u)unreached,labeled,scanned(分别是未到达,已标记和已访问三种状态)。源点s初始化为d(s)=0,S(s)=labeled;其余的点u则初始化为d(u)=,S(u)=unreached。算法由近及远地依次访问图中的每个顶点,并且保证性质:已访问过顶点(即S(u)=scanned)的临时距离d(u)就是正确的最短路径值。当访问一个顶点u时,松弛它所有出边(u,v),术语“松弛”的意思是,如果一条从源点s经过点u到达点v的路径长度更短,则相应地将距离d(v)更新。在处理s-t最短路径查询时,Dijks
10、tra算法在访问目标顶点t后可以终止。我们将这种Dijkstra算法的变体作为基准,以比较其他各算法的相对快慢。道路网中搜索空间可以粗略地认为是圆形,如图1所示。对于一个顶点数为n的图,平均而言算法需要访问n/2个顶点。由此可以看到,对于大规模道路网,Dijkstra算法的搜索空间庞大,导致查询效率十分低下。1.3 双向搜索双向搜索从源点s和目标点t交替地进行正向与反向Dijkstra搜索3,4。算法记录目前已发现的最短路径长度以及对应的路径表示,初始化为。在正向搜索中,当一条边(u,v)被松弛时,检查顶点v,若v被反向搜索访问过,则得到由s-u最短路径,边(u,v)和v-t最短路径组成的一条
11、路径。如果新路径比更短,则更新。反向搜索的执行过程类似。算法终止的条件是一个顶点同时被双向搜索访问过。相对于Dijkstra算法,双向搜索的加速比大约为两倍。因为搜索空间可看作圆形,而一个半径为r的圆面积是两个半径为r/2的圆面积之和的两倍。双向搜索算法的搜索空间示意如图2所示。双向搜索技术可以与很多加速算法结合,以进一步提升性能。2 目标向导方法观察Dijkstra算法的搜索过程可以发现,从源点出发的最短路径树围绕着源点均匀而缓慢地展开,使其在发现目标之前需要访问大量无关顶点,导致搜索空间巨大。衡量最短路径算法快慢的最主要因素为搜索空间大小,可用已访问顶点数表示(当然前提是算法必须依赖于搜索
12、,3.6节介绍的TNR算法采用表查找替代了搜索)。目标向导方法,顾名思义就是利用目标点的位置信息使搜索快速逼近目标点,从而达到减少搜索空间的目的。目标向导方法可以分为两类,一类是基于A*搜索5-7,A*搜索通过当前顶点与目标顶点的距离估计来引导顶点的选择,ALT是这类算法的代表。另一类是基于剪枝的方法8-19,此类算法利用预处理生成的辅助数据来判断s-t最短路径是否有可能通过某个顶点或某条边,若不然,则搜索不再松弛相应的顶点与边。此类算法的代表是Reach剪枝算法,几何容器法与边标记法,前者是利用顶点信息进行剪枝,而后两者是利用边上信息进行剪枝。以下各小节将详细介绍这几种典型算法。2.1 A*
13、搜索A*搜索的提出起初是用来加速游戏地图的搜索,也被称作启发式搜索5,6。其主体思想是:搜索过程考虑了当前访问点到目标点的距离,从而使搜索具有方向感。A*搜索使用一个势能函数t:VR,t(u),给出了从顶点u到目标点t的距离估计。Dijkstra算法与A*搜索的主要区别在于,前者在每一步的搜索过程中选取具有最小距离d(s,u)的点,而后者选取的是具有最小键值k(u)=d(s,u)+t(u)的点。给定了势能函数,定义边(u,v)上的约减代价l(u,v)=d(u,v)-(u)+(v),称势能函数是可行的当且仅当所有边上的约减代价都满足l0。如果t(t)0并且是可行的,那么对于任意点u,t(u),是
14、从顶点u到目标点t距离的下界估计,在这种情形下A*搜索一定能找到最优解。本文提到的A*搜索是指这样一簇算法:它们使用可行的势能函数t作为到目标点t距离的下界估计,并且t(t)=0。容易看到,在权重函数为l的图上执行Dijkstra算法与A*搜索算法是等价的。A*搜索可以与双向搜索技术结合起来。A*搜索算法的性能取决于势能函数的选择。特别地,若t给出了到目标点t的准确距离,搜索只会访问位于s-t最短路径上的顶点。最常见的距离估计是在给定顶点地理坐标的情况下,使用欧式空间中的两点直线距离作为势能函数。这个方法虽简单,但其加速比不大。若以行程时间作为边权重,则需要将欧氏距离除以可能的最快速度作为下界
15、估计。这是一个相当保守的估计,预期的加速比较少。Goldberg等甚至发现这种情况下搜索速度反倒不如Dijkstra算法7,原因在于搜索空间并没有大幅减少,却增加了不少额外开销。2.2 ALT算法ALT算法由A*搜索衍生而来,并利用地标(Landmarks)和三角不等式(Triangle inequality)计算下界估计7。关于最短路径的三角不等式如图3所示: 给定顶点u和v,假设u-v最短路径存在且唯一,另有一条经过顶点w的u-v路径P=u,,w,,v,则有三角不等式:d(u,w)+d(w,v)gt;d(u,v)(1)预处理过程中,先选取若干地标顶点LV,再计算图中顶点v与地标L之间的两两
16、最短路径长度d(v,L)和d(L,v)。对于顶点v和t,对每个地标L利用三角不等式有d(v,t)d(L,t)-d(L,v)和d(v,t)d(v,L)-d(t,L)。取这些下界估计的最大值作为d(v,t)的下界估计,记作d(v,t)。(v,t)=maxLd(L,t)-d(L,v),d(v,L)-d(t,L)(2)地标选取的好坏对于下界估计的紧致性以及最终的查询性能有着重要影响。假设要选取k个地标顶点,一个贪心方法如下:首先随机选取初始地标v0和距离v0最远的顶点v1,将v1加入地标顶点集SL中;在每次迭代过程中选取距离当前地标顶点集最远的点vi加入SL中,直到k满足个数要求。对道路网而言,在地图
17、边缘选取地标往往能给出良好的下界。实验表明,使用16个地标顶点就可在包含1 800万个节点的欧洲道路网上达到约27的加速比。然而,ALT算法空间开销较大,因为需要记录2|VSL|个距离。总体而言,ALT算法预处理较快,加速比可观,但在大规模图上空间开销会较大。2.3 Reach剪枝算法Reach的概念由Gutman在2004年首次提出8。定义1 Reach 给定s-t最短路径P以及P上的一点v,定义顶点v关于路径P的reach值r(v,P):=min(d(s,v),d(v,t)。在整个图G中v的reach值则定义为r(v,G):=maxpr(v,P)。换句话说,顶点v在图中的reach值就等于
18、,在所有包含点v的最短路径P中,关于路径P的reach值r(v,P)的最大者。从定义不难看出,顶点v必须位于某一条较长最短路径的中间位置时,reach值才会较大。在Dijkstra搜索的过程中,如果点v的reach值满足不等式:r(v,G)lt;min(s,v),(v,t)(3)那么Dijkstra算法不再将顶点v插入优先队列中,其中表示从s到v距离的下界估计。通俗地讲,当Dijkstra搜索遇到的顶点v的reach值太小,以至于无法通过点v到达(reach的本意即为到达)目标点时,就忽略该点。为了计算所有顶点的reach值,最直接的方法就是计算全源最短路径,但预处理的时间开销太大,达到了O(
19、n3)。一个折中的方法是计算reach的上界估计,不妨记作因为有所以只需要满足不等式:(v,G)lt;min(s,v),(v,t)(4)这样式(3)也就自然满足了,其代价就是剪枝剔除的顶点减少了。计算reach上界的过程如下:首先以每个顶点为根,计算其局部最短路径树并得到一部分顶点的reach上界;删除已计算出reach上界的顶点,对图进行收缩;不断迭代地执行以上两个步骤,直到大多数顶点的reach上界都被计算出,剩下顶点的reach上界定义为无穷大,即它们不会被剪枝。实验结果表明,在约为40万个顶点的图上经过两个多小时的预处理,最短路径查询的加速比约为10.06年,Goldberg等将Rea
20、ch算法与双向搜索结合,并且通过添加捷径,采用更紧致的reach上界等手段,极大地降低了预处理时间,提高了Reach剪枝算法的查询速度,在欧洲道路网上只需1.5小时的预处理就能获得约1 258的加速比9,10。2.4 几何容器法几何容器法是指示牌思想的一种实现11,12,它通过边上的预存信息排除不可能位于最短路径上的边,以达到减少搜索空间的目的。所谓的指示牌是指每条边上都记录路标信息,用以指示目的地是否可能通过该条边达到。一个基本的观察结果是:如果某条边e不是任意一条到目标点t的最短路径上的起始边时,在计算到点t的最短路径时可以忽视该边。形式化地说,对于图中的每条边e,用集合S(e)表示为以e
21、为起始边的最短路径所能到达的顶点集合。由于精确地保存每个集合需要相当大的空间开销,达到了O(mn),因此可以放宽限制使用一个几何容器C(e)(矩形、圆、扇形等)来代替集合S(e),需满足的条件是集合S(e)中的所有点都落在几何容器内。在执行Dijkstra算法的过程中,只需要松弛几何容器包含着目标点的那些边。Wagner等还研究了选取不同几何图形作为几何容器对算法性能的影响,结果发现简单的闭包矩形查询速度最快13。该算法存在一个致命缺陷:预处理过程往往需要计算全源最短路径,其代价非常昂贵。因此,目前尚未有人在大规模道路网上报告其实验结果。2.5 边标记法边标记法描绘了另一种基于指示牌思想的方法
22、14-16。类似地,用集合S(e)表示以e为起始边的最短路径所能到达的顶点集合,由于受制于空间开销,该算法将顶点集划分成p个区域,用来近似地表示集合S(e)。形式化来讲,函数r:V1,2,,p为每个顶点分配一个区域标号(对于有二维布局的图来说,一个简单的划分办法就是将图划分成网格,同一个网格内的顶点拥有相同的区域标号)。对于每条边e,用p位位向量be:1,,ptrue,false表示边上的标记信息,每一位对应于一个区域;对于任意区域i1,2,,p,be(i)置为true当且仅当,存在一条到区域i中某点的最短路径P使得边e是P上的起始边。在s-t最短路径查询中,目标点t所在的区域标号记作j,那么
23、算法的搜索空间会被限制在满足be(j)=true的那些边所导出的子图中。一个潜在的问题在于,一旦搜索进入了目标区域内,标志位信息就变得无用,通常可以使用双向搜索来避免此问题,一般来说正向搜索和反向搜索会在路径中央相遇。该方法的空间开销为O(pm),特别地,如果p=n并且为每个顶点分配各自的区域标号,该方法就相当于存储了全源最短路径,Dijkstra算法会直接找出最短路径,而忽视所有无关的点和边。边标记法的查询算法简单,具有挑战性的是预处理。最直接的方法就是执行全源最短路径算法。一个较好的改进是仅在每个区域的边界点上计算最短路径树,因为想要到达某个区域的内部点必须经过该区域的边界点。另外,在区域
24、个数不变的情况下,巧妙地划分图以减少边界点的数量,同样有助于降低预处理时间。Mhring等研究了网格、四叉树、k-d树和METIS17等不同的划分方法对查询性能的影响,结果表明k-d树和METIS的查询性能最佳18。Hilger等通过对每个区域仅执行一次Dijkstra搜索而进一步改进了预处理算法,实验表明在欧洲道路网上经过18个小时的预处理,获得了约3 950的加速比19。边标记法的优势在于查询算法的简洁、可观的性能以及较低的内存消耗。该方法的劣势在于预处理时间仍然很慢,难以应对边权重变化的动态场景;有时中等距离路径的查询性能会比较差,原因是两个点相距不太近,却又落在了同一个区域或是相邻区域
25、内。3 层次化方法目标向导方法能够有效地减少Dijkstra算法的搜索空间,但其局限性在于搜索空间的下界正是最短路径中的顶点个数,而在大规模道路网上路径的平均顶点数可达上千(欧洲道路网和美国道路网的数据分别为1 373和4 53720),一般而言较好的目标导向算法的搜索空间为路径顶点数的310倍,这就使得搜索空间仍达到了上万个顶点,阻碍了查询性能的进一步提升。层次化方法克服了这个缺陷,它通过挖掘道路网内在的层次特性并构建层次结构来降低搜索空间。层次化方法可分为两类,第一类为分割法21-25,它利用道路网的平面特性对图进行分割,再预计算分块边界点之间的距离,以此构建高层网络。第二类是基于节点重要
26、性的方法20,25,28-31,33-36。这类方法大都基于以下观察:在最短路径查询中,道路网的一些节点(如高速公路的入口点)的访问频度比另一些节点(如城镇街道的岔口)更高。具体来说,算法的预处理过程首先需要分辨顶点的重要性,对于不重要的顶点进行收缩,同时添加一些捷径以保证图中其余顶点间的最短路径长度不变,不断迭代这个过程就自底向上构建了层次结构,其关键点在于如何清晰地定义节点的重要性。此外,除了计算最短路径,层次化方法在图的表示,可视化与概述等方面也有广泛应用37。3.1 分割法分割法将道路网进行划分,在分割后的每个块中计算所有边界点之间的距离;当搜索经过该块时可以直接在边界点上跳跃,而不需
27、要搜索内部顶点。为了加速块内的局部查询,该方法可以对块再进行递归划分。由于道路网几乎是平面的,因此一些针对平面图的技术往往也能适用于道路网。平面分割定理22给出了边界点大小的上界:对于任意n个顶点的平面图,存在大小为O()的分割点集合,可以将平面图分割为两个不超过2N/3个顶点的连通分量。实际中往往要求各块大小要均匀,块与块之间的连边尽可能少,总共的边界点数目尽可能少。采用这类思想的具体实例有很多。例如,Klein研究发现对于带有非负权重的有向平面图,可在O(nlog2n)时间内构建了密度距离图,其查询时间为O(log2n)23。Thorup发现几乎常数时间内就可以处理准确度为(1+)的近似最
28、短路径查询,其预处理开销和内存开销均为O(nlogn/)25。由于这些理论所使用的技术较复杂而且空间开销大,难以真正地应用于实践。3.2 基于分割的多层算法基于分割的多层算法是另一个基于分割法的实现25,算法提出了多层覆盖图的概念。定义2 多层覆盖图 对于给定图G=(V,E)和一系列顶点子集V:=V0V1VL,定义多层覆盖图为g:=(G0,G1,GL),其中G0:=G,对于lgt;0,有Gl:=(Vl,El),El:=(s,t)VlVl|,在Gl-1中存在最短路径P=s,u1,u2,,uk,t满足i,uiVl。换句话说,对于每对顶点(u,v)VlVl,边(u,v)El当且仅当在图Gl-1中的u
29、-v最短路径不包含在Vl中的内部顶点,并且权重wl(u,v)等于Gl-1中u-v最短路径的长度。在图Gl-1中选取分割点Vl时应保证:在顶点集Vl-1-Vl的导出子图中,各个连通分量都较小并且顶点数均匀。多层覆盖图的构建方法如下,从每个分割点uVl出发,在图Gl-1中执行Dijkstra算法直到所有相邻连通分量的分割点vVl都被访问过,把相应的边(u,v)连同其权重dGl-1加入到边集El。查询算法是一个双向Dijkstra搜索过程,当搜索位于Gl中某个连通分量内部时,边集ElEl+1EL中的所有边都需要进行松弛;当搜索访问到Gl中连通分量的边界点时,仅需要松弛El+1El+2EL中的边。该算
30、法的不足之处在于,当层数l较大时Gl比原始图G0稠密得多,使得原本缩减的搜索空间又略微增加。另外,在大规模道路网中计算分割点也相当耗时。Willhalm在顶点度数大都为2的道路网上进行实验,得到了10左右的加速比26;Holzer等在10万个节点的小规模道路网上获得了52的加速比25。3.3 层次公路算法商业导航系统通常使用启发式层次方法27。其基本思想是,当搜索围绕源点(目标点)展开时,道路网中所有路段都需要考虑。当搜索离开源点(目标点)所在的局部区域时,搜索就仅限于包含重要路段的高速公路网上。若将这种思路进行迭代就生成了层次公路结构。如何定义层次公路是问题的关键点,也是难点所在。启发式方法
31、根据路段类型信息(国道、高速公路、城镇街道等)对边进行分类。这种分类方法需要人工标注而且不能保证路径是最优的。受此思想启发,Sanders等提出了层次公路HH(Highway Hierarchies)算法28,29。该算法并非盲目地依赖于路段类型信息,而是在预处理中自动地将顶点和边分层,并且保持所有最短路径不变。算法中,顶点u的局部区域N(u)被定义为包含距离u最近H个顶点的集合,这里H为调优参数。那么一条边(u,v)属于公路网(highway network)当且仅当存在顶点s和t满足边(u,v)位于s-t最短路径中,并且顶点v不在s的局部区域N(s)中,u也不在t的局部区域N(t)中。简单
32、来说就是公路边(u,v)不能太靠近顶点s或t。构造层次公路的算法包含两个交替进行的步骤:边约减和顶点收缩。边约减过程将去除非公路边。具体来说,从每个顶点vV出发计算局部最短路径树Tv,而后在Tv中筛选公路边。顶点收缩过程将去除度数较低的顶点,并同时引入一些捷径以保持其余顶点间的最短路径长度不变。查询算法在双向搜索的基础上进行了修改,当搜索离开源点(目标点)的局部区域时就切换到更高一层的公路网上。另一个不同之处在于,双向搜索在交汇时算法终止,而HH查询算法必须等到双向搜索都结束后,再从所有交汇顶点查找最短路径。图4显示了HH算法搜索空间示意图。层次公路是首个能够在毫秒级别处理诸如美国道路网这样大规模图的加速算法,加速比达到了8 320。这主要归功于两点:第一,道路网在以几何级数逐层收缩的同时仍保持稀疏性与平面性,换言之,层与层之间存在某种自相似的关系;第二,预处理算法从每个顶点出
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1