此文章目标人群为还未理解A*算法的或想更进一步了解它的人士。
给定有向图的两个结点求他们之间长度最短的路径,可以用到A*算法,算法在下面列出。
对图中某一结点N以及起始结点src、终止结点dst:
整个算法在执行过程中,会从src结点开始对图中的结点进行遍历(可能某些并不会被遍历到),算法在遍历到某个结点时,会记录下src到该结点经过的路径,该路径的长度就记为g(N)。在算法初始化时,很自然的,src结点的g值为0,其它的结点g值为∞,表示还未被遍历到。另外,某个结点可能被遍历多次,例如:
A
↗ ↘
src D → ….
↘ ↗
B
算法(可能)通过src->A->D这条路径遍历D之后,又折回去访问B,接着再访问D。
要谨记,结点的g值是动态生成的——在第一次遍历到它的时候生成(并且可能在以后遍历的时候更新,这是后话),不要被它吓到,如果你愿意,你可以就当它是从起始点到这一点的某条路径的长度。
h(N)表示结点N到目标点dst的“预估”长度。算法开始前,每个结点的h值都是预先确定好的。(怎么确定暂且不论)A*算法的一个思想是:路径是慢慢发现的,你发现了中途某个结点后,并不知道它离你的目标点准确有多远,只能知道个大概。不要急,这个东西在后面会慢慢解释。
g(N)和h(N)的和记为f(N)。f(n)表示了算法的遍历趋势,请铭记于心,g(N)代表这个节点离起始点的(本次遍历时经过)距离,h(N)代表这个节点离终点的(预估)距离。
有了上述概念,我们先来看看算法的形式化的步骤:
1. 建立两个容器,分别名为open和closed;
2. 将src结点添加到open中,置src结点的g值为0,置src结点的parent为null;
3. 只要open容器非空,执行以下步骤:
记open容器中f值最大的结点为cur,将cur移入closed中并将其从open中删除
如果cur就是dst结点,那么算法结束,从cur开始追朔parent生成的路径就是最短的路径;接下来,对cur结点的每一个相邻结点n:
如果n在close中
略过它,遍历下一个相邻结点
如果n在open中
如果cur的g值加上cur到n这条边的距离小于已存在的n的g值,那么更新已存在的n的g值为前者,更新其parent为cur;否则什么也不做。
否则
将它添加到open中去,其g值设为cur的g值加上cur到n这条边的距离,其parent设为cur
在证明算法前,我们必须对h函数的选择条件加以限制。
h*(N)表示结点N到dst的实际距离
根据h函数选取条件h(N)<=h*(N):
d(i,j) = h*(i)-h*(j)
h*(i) > h(i)
h*(j) > h(j)
因此:
d(i,j) < h(i) - h(j)
记最短路径(path)上的点为(v0, v1, v2, ..., vk, ..., vt),其中k=0...t,v0为起始点,vt位目标点。
结论0:
i通过i->...->k->...->j这条最短路径p到达j,k是这条路径上的一个中间点,那么i->...k也是i到k的最短路径。
证明:
如果i->...k不是i到k的最短路径,而i->k的最短路径记为p1,那么p1+(k->...->j)才是i到j的最短路径,与p是最短路径相悖。
结论1:
对于最短路径上的结点N,当它前面的结点进入close时,它的g值就是它距起始点的最短距离,因为当N-1进入close时就会对N的值进行指定或更新,而这个值就是最小的。
结论2:
对于最短路径上一点vj前面的所有点,但凡vj进入open,这些点要么都已经进入closed,要么至少有一个就在open中,下面是证明:
因为v0是起始点,因此v0一定会最先进入close,并展开v1到open,此时的g(v1)为起始点到v1的最短路径;
此后,设N=1,2...j-1,对于在open中的vj和它前面的最短路径上的点
因为 h(N)-h(j)<d(N,j) // h函数选取条件
g(j)-g(N)>d(N,j) // 因为此时g(N)是起始点到N的最短路径长度(见结论0)
// g(j)是起始点到j的当前路径长度
// 但是此时(g(N)对应的路径)+(N,j)才是最短的路径
// 因此g(j)>g(N)+d(N,j)
所以 (g(j)-g(N))-(h(N)-h(j))>0
即 f(j)-f(N)>0
即 f(N)<f(j)
可见f(v1)<f(vj),因此如果v1、vj同时在open中(vj可能通过其它路径被访问过),那么v1一定会先于vj进入close,并展开v2到open(如果它不在)或更新它的g(v1),此时的g(v1)为起始点到v1的最短路径
可见f(v2)<f(vj),因此如果v2、vj同时在open中(vj可能通过其它路径被访问过),那么v2一定会先于vj进入close,并展开v3到open(如果它不在)或更新它的g(v2),此时的g(v1)为起始点到v1的最短路径
...
可见f(vj-1)<f(vj),因此如果vj-1、vj同时在open中,那么vj-1一定会先于vj进入close,并展开vj到open(如果它不在)或更新它的g(vj),此时的g(vj)为起始点到vj的最短路径
换句话说,结论2表明:最短路径上的点会按先后顺序进入close。
注意,结论3只是说明最短路径上的点会按先后顺序进入close,并未说明在这些点会按先后顺序进入open,也并未说明它们之间是否穿插着其它点进入close。
例如:
10 B 20
↗ ↘
A D
↘ C ↗
14 6
起点为A,终点为D,现用A*算法求最短路径
为了求出最短路径,令
h(A)=10(小于A到D实际最短距离)
h(B)=5(小于B到D实际最短距离)
h(C)=4(小于C到D最短距离)
h(D)=0
起始时:
open = {A(g=0 h=10)}
close = {}
1. open中A最小,加入A到close中,对A的后代B和C,把他们都加入到open中,于是
open = {B(g=10 h=5), C(g=14 h=4)}
close = {A}
2. open中B最小,加入B到close中,对于B的后代D,把它加入到open中,于是
open = {C(g=14 h=4), D(g=30 h=0)}
close = {A, B}
3. open中C最小,加入C到close中,对于B的后代D,它已经存在于open中,但是因为c->d的g值更小,于是更新D的g值为C的g值加C到D的边,于是
open = {D(g=20 h=0)}
close = {A B C}
4. 从open中取出D,算法结束
可以看到,虽然终点D在步骤2进入了open,但由于f值比它小的C一直存在——直到C进入close,它才得以进入close。
另外,就算终点提前进入了open,提前得到了g值,那条最短路径出open时也会把g值更新为最短的。
分享到:
相关推荐
在实验中,你可能会遇到如内存管理、循环引用、最优性证明等问题,这些都是理解和优化A*算法的重要环节。通过实际编写代码,你可以深入理解A*算法的工作原理,以及如何利用启发式信息有效地进行搜索。 总结起来,这...
**A*算法详解** A*算法是一种启发式搜索算法,广泛应用于路径规划、游戏AI、图形处理等领域。它结合了Dijkstra算法的最优性保证和...这展示了状态转换的数学基础,进一步证明了A*算法在解决此类问题时的有效性和效率。
A*算法在各种寻路场合中的广泛应用证明了其强大的性能。其寻路原理简单明了,而且具有高度的灵活性和效率。通过合理地设计启发式函数H值,A*算法可以快速地找到一条最短路径或最佳路径,这使得它在游戏开发、机器人...
在传统的A*算法中,路径的生成是通过节点的评估函数来完成的,而方向A*算法在此基础上加入了方向因子,使得路径在满足最短路径的同时,还能进行优化以适应特定环境。这种改进对于温室机器人来说尤为重要,因为在温室...
研究证明了改进后的算法能够通过调整障碍搜索矩阵的尺寸,获得不同的安全间距,从而在不同环境和地图中保证不同类型的机器人的安全。更重要的是,相较于传统A*算法,在复杂大环境中的路径规划速度提高了28.07%,搜索...
为了解决十五数码问题, 常用的方法是 A 算法, A 算法的好坏完全决定于启发函数 h 的选择. 在 15 数码问题中, 常用的启发函数有错位数和曼哈顿距离, 但这样的启发函数距离真实的代价差距还是很大的. 同时我们可以注意...
实际机器人路径规划问题经常需要考虑路径的转弯约束以及路径起始/目标角要求,为此提出一种基于方向约束的A*算法.新算法区分同一路径点处不同方向的各条路径,通过定向扩展机制来满足路径方向约束,并采用节点合并策略...
A*算法在许多领域已经被证明是非常快速的,尤其在使用膨胀启发式(heuristics)时,实际上的启发式值是通过一个膨胀因子(通常大于1)来扩大。虽然A*算法是次优的,但它对于很多领域来说是快速的。ARA*算法的一个...
在本篇人工智能实验报告中,我们深入探讨了五个核心主题:决策树、循环神经网络、遗传算法、A*算法以及归结原理。这些是人工智能领域中的关键算法和技术,它们在解决复杂问题时扮演着重要角色。 首先,让我们来了解...
为了解决十五数码问题, 常用的方法是 A 算法, A 算法的好坏完全决定于启发函数 h 的选择. 在 15 数码问题中, 常用的启发函数有错位数和曼哈顿距离, 但这样的启发函数距离真实的代价差距还是很大的. 同时我们可以注意...
A*搜索算法是一种高效、广泛应用的启发式搜索算法,由Hart、Nilsson和Raphael在1968年提出,主要用于寻找最优路径问题。它结合了深度优先搜索(DFS)和广度优先搜索(BFS)的优点,同时通过启发式函数优化了搜索效率。 ...
**A*(A-star)算法**是一种启发式搜索算法,常用于路径寻找和最短路径问题。它结合了Dijkstra算法的全局最优性和Greedy最佳优先搜索的效率。A*算法通过使用一个评估函数来预测从起点到目标的估计成本,这个函数通常...
迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。
提出以一致性原则动态形式为基础的动态A*算法(dynamic A* algorithm,DA* aIgorithm)并证明了在两节点间动态下界满足一致性原则动态形式前提下,该算法能够求解满足先进先出原则的动态网络中两节点间最短路径问题。...
在实际运行过程中,A* 算法会不断地从OPEN表中取出f值最小的节点进行扩展,直到找到目标节点或证明无解。由于启发式函数的存在,A* 算法通常比Dijkstra算法更快,因为它总是优先考虑更接近目标的节点,避免了不必要...
例如,Park等人使用遗传算法为无人机提供冲突解脱策略,而Stefan Lehmann则利用A*算法建立了飞行冲突解脱模型,通过模拟管制员解决飞行冲突的认知决策过程,证明了此模型算法在应用于复杂动态系统时的有效性。...
该算法被应用于自主研发的“智能先锋”号系列无人驾驶车辆上,实车试验以及它们在“中国智能车未来挑战赛”中的优异表现证明该方法能够在栅格地图中求解出一条更优的可行驶路径,可以显著提升无人驾驶车辆行驶的效率...