路网最优路径算法之一分层搜索
1 背景
前面介绍了关于双向及启发式的搜索,它们均可以实现了效率的倍增。但是应用到长距离(例如武汉——杭州大于500公里)的搜索时,平均效率存在100ms级甚至s级的耗时,显然这样一个面对广大用户群的互联网服务引擎效率是不可接受的,那么有没有优化的方向可以实现数量级的提升?
但人类对效率与正确的极致追求也是不止境的。关于双向及启发式搜索,它们的优化初衷均是一致的:缩短搜索范围。有人想到另一个路网搜索优化的方向:稀疏搜索路网密度——分层算法。
2 分层算法
假设有个长距离路径搜索的case1,某人春节后从A省所在的a县城返到B省所在的b县城,从人的认知心理学角度进行搜索的过程:
a 正向搜索:首先寻找a县城出发地周围内(例如20km)所在的主路或环路,然后再寻找县城周围内(30km)去A省所在省道的出口,再然后上国道高速路等。
b 反向搜索:类似正向搜索的行为过程。
正是由于路网具有等级差异的特征,所以路网分层算法应运而生了:我们会把路网根据国家规定或行业定制着不同的等级规则(主干道、省道、国道高速),进行归类与分层。
当在出发地开始寻路时,首先仅考虑环路或主干路的搜索在30km的范围,然后继续仅考虑省道的搜索在80km的范围内,最后继续考虑高速等道路的搜索在100km的范围,这样搜索路网的密度会大大下降。可是不幸的是,这样的搜索直觉上是对的,但理论上未必靠谱。
举个不恰当的反例case2:有人从城市武汉出发去西藏林芝等区自驾游,驾驶随着离出发地距离渐远的过程,走向高层的路网行驶,经过了重庆和四川,这时得经过一段“低等级的碎石路”才能入藏,可是“这段低等级的碎石路”可能已不在高层的候选路网中了,导致此次寻路失败。
人类对自然与社会的认知过程,通常会先有直觉上的假设,然后会有理论及量化的证明。这也是社会科学和自然科学的奥妙关系。而HH路网处理算法的特点:正是对所有路网的重要性进行量化的分层算法之一。
3 HH算法
3.1 背景
路网由一堆节点和边组成。路网最优路径的搜索耗时,是与节点和边规模的平方成正比的。其算法设计初衷计算任意节点对最优路径时,在尽量稀疏的路网上进行搜索,来降低路网搜索规模,而又能同时保证结果的最优正确性。
3.2 思路
a 预处理阶段:采取分层的方法不断迭代,当前层的路网是由低一层的路网不断进行干掉拓扑点和边,生成新的逻辑路网的结果。
并且每一层逻辑路网满足下面两个性质:
条件1:每一层的逻辑路网是其低一层逻辑路网的子集
条件2:每一层的逻辑路网中,任意拓扑点对的最优路径,一定属于当前层。
b 实时查询阶段:在逻辑路网上进行最优路径的查询(比原始路网搜索快近1000倍)
3.3预处理
预处理的过程:基于当前路网不断迭代,进行干掉拓扑点和边生成更高层逻辑路网的过程。
3.3.1干掉节点(contract_node)
a 背景
试图思考下,我们干掉一个节点时,其入边和出边也相应的也会干掉了,但为了保证拓扑的完整性,会增加相应的逻辑边。
如果一个节点node,其入边个数和出边个数分别是nDegIn和nDegOut,contract其node时,去掉了其入边和出边的个数是(nDegIn+nDegOut),而最坏情况下,会引入的逻辑边的个数是inDeg*outDeg。显然,如果nDegIn与nDegOut均大于1时,值nDegIn*nDegOut大于值(inDeg+outDeg)的,并且nDegIn和nDegOut越大,其差值越大。
b 条件
现在的矛盾:我们想去掉一些不是那么重要的节点,而又不想引入更多的逻辑边,所以引入contract因子contract_factor,通常取值1-2之间。当且仅当节点满足条件时:(nDegIn*nDegOut)<(nDegIn + nDegOut)*contract_factor,才会contract掉这个节点。
3.3.2 干掉边(build partial_tree 和 select_highway)
a 对于每个节点,基于给定的neighbour_size,计算其邻域半径neighborhood_radius
b 对于每个节点,计算每个节点的最优路径树partial_tree
c 对于每个partial_tree,对其每个叶子节点进行边的回溯,按照既定的规则,选取符合条件的边为更高层的边
4 路网算法优化方向
最后对路网算法优化的方向做个简单总结:
a Bi-Directional
b Heuristic (策略:缩减搜索范围,Dijkstra搜索空间是近似圆,A*搜索空间近似椭圆)
c Hierarchy(shortcut/contration,策略:缩减搜索密度,通常搜索密度为原始路网的近似百分之一,并且能保证结果正确性。典型算法如:HH、HNR、CH)
d TimeTable(预存储和实时取)
并且上面4个优化方向互不冲突,通常可以任何组合同时使用。
参考
1 http://algo2.iti.kit.edu/routeplanning.php