目录
从一次遍历分析:为什么A*算法比Dijkstra算法搜索要少?
依旧是点赞点赞点赞!!!希望对你有帮助。
A*算法的概述
A算法是一种用于在图形或网格中查找最短路径的启发式搜索算法。它通过结合已经搜索过的路径代价和从当前节点到目标节点的估算代价(即启发函数),来评估每个节点的优先级,并优先搜索可能性最高的节点,从而高效地找到从起点到终点的最短路径。
启发式函数
A*算法的核心在于其代价评估函数F(n),该函数由两部分组成:
- G(n):从起点到当前节点n的实际成本(或称为距离)。这是已经确定并且不会改变的。
- H(n):从当前节点n到终点的估计成本,即启发函数。这个函数的选择对算法性能至关重要,因为它决定了搜索的方向性和效率。理想情况下,H(n)应该尽可能接近从n到终点的实际最短成本,但又不应超过这个值(否则算法可能不是最优的)
启发函数的估计成本一般是由两个部分组成:欧几里得距离和曼哈顿距离。这个两个距离分别是什么呢?我将用最简单的方法告诉你们:
设当前点为A,目标点为B,计算AB之间的评估成本:
欧几里得距离就是斜边c。
曼哈顿距离就是直角边之和a+b。
A*算法的搜索步骤
算法文字叙述内容枯燥,但依旧要贴。
列表初始化定义
A*算法使用两个主要的列表来管理搜索过程:
- OPEN列表:包含待评估的节点。这些节点是可能的候选路径的一部分,但尚未被完全评估。
- CLOSED列表:包含已经评估过的节点。这些节点在搜索过程中已经被考虑过,并且不会再次被考虑(除非发现通过新的路径到达它们的成本更低)。
程序过程
-
初始化:将起点加入OPEN列表,并设置其G(n)和H(n)值(起点到自身的实际成本为0,启发函数值根据起点和目标点的相对位置估算)。
-
循环搜索:
- 从OPEN列表中取出F(n)值最小的节点n(即最有希望是路径一部分的节点)。
- 如果n是目标节点,则路径已找到,停止搜索。
- 否则,将n从OPEN列表移至CLOSED列表,并考虑n的所有邻居节点。
-
邻居节点处理:
- 如果邻居节点已经在CLOSED列表中,则忽略。
- 对于每个不在OPEN列表中的邻居节点,计算通过n到达它的新G(n)值(即G(n) + 从n到邻居节点的成本)。
- 如果这个新G(n)值小于邻居节点在OPEN列表中的G(n)值(或者邻居节点不在OPEN列表中),则更新邻居节点的G(n)值、F(n)值(因为H(n)不变),并将其父节点设置为n,然后将其加入或更新在OPEN列表中。
-
结束条件:如果OPEN列表为空,则表示没有找到路径(尽管在大多数实际应用中,这种情况很少见,因为通常至少存在一条从起点到终点的路径)。
-
路径重构:一旦找到目标节点,就从目标节点开始,沿着父节点指针回溯到起点,形成最短路径。
A*算法图文结合讲法:花最少的车费同时最快到达目的地
A*算法的趋向性搜索
A*算法一般运用在栅格地图中较多。
图释:红色为起点,绿色为终点,纯黑色为障碍物,深灰色为搜索过的区域,蓝色为最终路径,灰色带数字为与搜索区域。
可见A*算法在搜索路径过程中会向着趋向目标点(绿色)的方向搜索,图示中绿色框就不会搜索到,大大减少了算力资源的浪费,提高了算法的实时性。相比于迪杰斯特拉算法无脑的向着四周扩展,A*算法大大提高了算法的质量。
A*算法相比于Dijkstra算法的优势
讲到这里可能大家对于A*算法可能还是不太理解,为什么A*算法比Dijkstra算法要好呢?下面给出两片图:
上面的是Dijkstra算法,下面的是A*算法,可见A*算法搜索区域大大减少。
从一次遍历分析:为什么A*算法比Dijkstra算法搜索要少?
Dijkstra算法:根据计算代价,第一次遍历,起点作为父节点,显然2,4,5,7代价为1格,其它都是根号2格,那么下一遍历就是2,4,5,7作为父节点向外扩展。
A*算法:根据计算代价和启发函数的评估成本之和,第一次遍历,起点作为父节点,根据计算消耗的代价和评估的成本之和,显然5是消耗的代价和评估的成本之和最少的,那么下一遍历只有5作为父节点向外扩展。显然比Dijkstra算法方便很多。
谢谢观看!!!