Dijkstra算法从物体所在的初始点開始,訪问图中的结点。它迭代检查待检查结点集中的结点,并把和该结点最靠近的尚未检查的结点增加待检查结点集。该结点集从初始结点向外扩展,直到到达目标结点。Dijkstra算法保证能找到一条从初始点到目标点的最短路径,仅仅要全部的边都有一个非负的代价值。(我说“最短路径”是由于常常会出现很多差点儿相同短的路径。)在下图中,粉红色的结点是初始结点,蓝色的是目标点,而类菱形的有色区域(注:原文是tealareas)则是Dijkstra算法扫描过的区域。颜色最淡的区域是那些离初始点最远的,因而形成探測过程(exploration)的边境(frontier):
下图同样颜色的格子代表起点到达这些格子的代价是一样的,颜色越浅代表到达目标所须要的代价越大,Dijkstra算法均衡的向四面八方扩张,被扩张的每个格子都会记住它前一个消耗最少的那个格子,直到扩张区域包括目标点
最佳优先搜索(BFS)算法依照类似的流程执行,不同的是它可以评估(称为启示式的)随意结点到目标点的代价。与选择离初始结点近期的结点不同的是,它选择离目标近期的结点。BFS不能保证找到一条最短路径。然而,它比Dijkstra算法快的多,由于它用了一个启示式函数(heuristicfunction)高速地导向目标结点。比如,假设目标位于出发点的南方,BFS将趋向于导向南方的路径。在以下的图中,越黄的结点代表越高的启示式值(移动到目标的代价高),而越黑的结点代表越低的启示式值(移动到目标的代价低)。这表明了与Dijkstra算法相比,BFS执行得更快。
贪心算法:颜色同样的格子代表这些格子在理想状态下(没有障碍物的情况下)直线到达目标点的代价是一样的,从起点不停的像终点扩张,扩张的时候会记住前一个最小理想代价的格子假设碰到障碍物它会又一次选择新的理想代价最少的那一个格子直到到达目标格子
然而,这两个样例都不过最简单的情况——地图中没有障碍物,最短路径是直线的。如今我们来考虑前边描写叙述的凹型障碍物。Dijkstra算法执行得较慢,但确实能保证找到一条最短路径:
还有一方面,BFS执行得较快,可是它找到的路径明显不是一条好的路径:
问题在于BFS是基于贪心策略的,它试图向目标移动虽然这不是正确的路径。因为它只考虑到达目标的代价,而忽略了当前已花费的代价,于是虽然路径变得非常长,它仍然继续走下去。
结合两者的长处不是更好吗?1968年发明的A*算法就是把启示式方法(heuristicapproaches)如BFS,和常规方法如Dijsktra算法结合在一起的算法。有点不同的是,类似BFS的启示式方法常常给出一个近似解而不是保证最佳解。然而,虽然A*基于无法保证最佳解的启示式方法,A*却能保证找到一条最短路径。
我将集中讨论A*算法。A*是路径搜索中最受欢迎的选择,由于它相当灵活,而且能用于多种多样的情形之中。
和其他的图搜索算法一样,A*潜在地搜索图中一个非常大的区域。和Dijkstra一样,A*能用于搜索最短路径。和BFS一样,A*能用启示式函数(注:原文为heuristic)引导它自己。在简单的情况中,它和BFS一样快。
在凹型障碍物的样例中,A*找到一条和Dijkstra算法一样好的路径:
成功的秘决在于,它把Dijkstra算法(靠近初始点的结点)和BFS算法(靠近目标点的结点)的信息块结合起来。在讨论A*的标准术语中,g(n)表示从初始结点到随意结点n的代价,h(n)表示从结点n到目标点的启示式评估代价(heuristicestimatedcost)。在上图中,yellow(h)表示远离目标的结点而teal(g)表示远离初始点的结点。当从初始点向目标点移动时,A*权衡这两者。每次进行主循环时,它检查f(n)最小的结点n,当中f(n)=g(n)+h(n)。