Hybrid Astar 算法剖析和实现
Posted 穿越临界点
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hybrid Astar 算法剖析和实现相关的知识,希望对你有一定的参考价值。
在学习资料满天飞的大环境下,知识变得非常零散,体系化的知识并不多,这就导致很多人每天都努力学习到感动自己,最终却收效甚微,甚至放弃学习。我的使命就是过滤掉大量的无效信息,将知识体系化,以短平快的方式直达问题本质,把大家从大海捞针的痛苦中解脱出来。
文章目录
0 前言
本篇承接上篇,继续分析Hybrid Astar迭代搜索的核心流程。
1 迭代搜索的核心流程
1.1 遍历
迭代搜索的最终目标是找到一条从起点到终点的最短无碰撞可行使路径。
我们的思路就是一步步向前探索,迭代着向前找可行使路径,把所有的路径都遍历一遍,直到走到终点为止。
最朴素的遍历思想就是基于起始点状态先找它周边的状态节点,有碰撞的丢掉,没有碰撞的先都记录下来,本次迭代结束。下一次的遍历当然不能再基于起始点了,而是基于上次迭代/记录下来的/起始点周边的/无碰撞节点中的/一个(好绕),给它们起个名字吧——边界节点。本次基于边界节点进行遍历之后,又会产生一个新的边界节点,那这个老的边界节点怎么处理呢?此时这个老的边界节点已经不再是边界节点了,而是——界内的节点了,将这一点想明白很重要,因为这是遍历的 核心思想。
接下去的行为就是重复上面的动作——再基于一个边界节点,将它周边的无碰撞节点放入边界节点的集合,而将自己放入界内节点的集合——就这样迭代着向前扩张。
下面举两个例子,大家就非常清楚这个过程了。
一个是领土扩张的例子。历代皇帝在进行领土扩张时,都是从内向外一点点攻打城池完成的。新打下来的城池作为疆域,也就是我们上面提到的边界点(此时叫边疆点是不是更贴切呢),等大军继续向前扩张时,会派人驻守之前打下来的城池,此时这个城池已经交接给守军了,当然不能再叫边疆点,而是自己的疆土了,改个名字叫疆内点不过分吧?既然,有了边疆点、疆内点、那剩下的就是疆外点了,这是再自然不过的了。因此,大军扩张领土的过程就是急先锋将边疆点不断向外推进的动态过程。
再讲一个小朋友都能理解的例子——狗熊掰棒子的例子。只不过这个狗熊是21世纪的狗熊,聪明了一点,带了装玉米的袋子。对应我们前面提到的遍历过程,装到袋子里的玉米就是 界内点 ,拿在手里的就是 边界点 ,长在玉米杆上的玉米就是 界外点 。
1.2 三个集合
从上文的遍历过程中,我们接触到了三类点:边界点、界内点和界外点。用数学语言描述就是三个集合。也就是业界内经常提的OpenSet(或OpenList)和CloseSet(或OpenList),分别对应了边界点和界内点。有人可能就问了,那界外点呢?界外点对应的集合是 O p e n S e t ∪ C l o s e S e t OpenSet\\,\\cup\\,CloseSet OpenSet∪CloseSet 的补集。
这三个集合非常重要,后面代码的实现都是围绕这三个集合进行的。
1.3 终止条件
Astar的终止条件只有一个,就是一旦发现边界点是目标点立即结束遍历。
相比之下,Hybrid Astar的终止条件就比较复杂一些,现将其罗列如下:
- 发现边界点和目标点状态向量差距在可接受范围内时结束遍历。
- 发现从当前边界点可以直接构造一条连接目标点的无碰撞R-S曲线时结束遍历。
- OpenSet中的点超过一定量级仍无法完成搜索时结束遍历。
- 超时结束遍历。
1.4 cost和优先级
- cost
广度优先搜索算法没有cost的概念——认为走任何路径消耗是相等的。但真实情况往往不是这样,山路和水路和平地显然是不同的,车辆前进和后退肯定也是不同的。为了更好的描述选择不同路径带来的损耗,引入cost的概念。
广度优先搜索算法 + cost(only g) => Dijkstra算法。Dijkstra算法中 f c o s t ( n ) = g s t a r t ( n ) f_cost(n) = g_start(n) fcost(n)=gstart(n) ,也就是说仅仅计算当前节点到起始点的cost。
Dijkstra算法 + cost(plus h) => (Hybrid) Astar算法。(Hybrid)Astar算法只是将Dijkstra算法中的cost公式改进了一下 f c o s t ( n ) = g s t a r ( n ) + h e n d ( n ) f_cost(n) = g_star(n) + h_end(n) fcost(n)=gstar(n)+hend(n) ,计算cost时不仅仅只考虑当前节点到起点走过的距离,而且加入了启发项——考虑当前节点到终点 可能 要走的距离。加上启发项的本质是另搜索过程使用到了终点信息,可以一眼看到终点,而不是蒙着眼睛乱转。好处是可以提升搜索效率,更快地搜索到终点。
为什么可以提升效率呢?回答了这个问题也就搞清楚了(Hybrid)Astar算法提升搜索效率的 核心思想 。
- 优先级
(Hybrid)Astar算法提升搜索效率的 核心思想 就是 基于优先级调度 。对操作系统比较熟悉的同学对此肯定有强烈的亲切感了~~
设计一个优先级队列,将OpenSet中的状态节点交给该优先级队列管理,节点对应的cost值作为该节点的优先级,cost值越小,优先级越高,也就意味着先被调度。先被调度就意味着先探索该节点周边的节点。
(Hybrid)Astar算法计算cost值时加入了启发项,这就意味着距离终点近的边界点会在遍历时被优先遍历,而且它临近的节点(子节点)在加入该优先级队列时也是有机会排到上轮遍历,甚至是上轮、上上轮就加入该优先级队列的子节点的前面(打破了论资排辈,Dijkstra算法就打破了)。因此,(Hybrid)Astar可以朝着目标快速前进。
总结一下就是:
- Dijkstra基于优先级调度打破了“论资排辈”,新的子节点可以凭“能力(cost越小代表能力越强)晋升”。
- (Hybrid)Astar引入启发项,相当于引入的“目标管理机制”,朝目标前进的子节点更容易得到“晋升”。
1.5 路径回溯
我们最终的目的是要获取一条从起点到终点的路径,因此在遍历结束后(前提是正常结束)需要回溯出一条路径。
如果在遍历时记录下每个状态节点是由哪个边界节点遍历而来的就很容易从终点回溯出一条指向起点的路径,然后在将该路径reverse就是从起点到终点的路径了。
这个过程描述起来看着挺复杂的,代码实现是比较简单的,详细流程我们在下一篇的代码实现中再进一步说明。
2 总结
本篇主要介绍了Hybrid Astar算法迭代搜索的核心流程和两个核心思想。当然,只看文字说明是无法完全吃透该算法的,还是需要结合代码来理解每一个细节。下一篇我们就对该算法的搜索流程进行代码实现和讲解。
恭喜你又坚持看完了一篇博客,又进步了一点点!如果感觉还不错就点个赞再走吧,你的点赞和关注将是我持续输出的哒哒哒动力~~
以上是关于Hybrid Astar 算法剖析和实现的主要内容,如果未能解决你的问题,请参考以下文章