A*算法浅析

来源:互联网 发布:android 7.0源码 编辑:程序博客网 时间:2024/06/15 17:31

很久没写博客了,今天就来讲讲A*算法吧。


前言:

比赛中,搜索是一种简单有效的拿分方法。但搜索也分很多种,如何搜索效率更高,可以拿到更多分,是一个很有意义的问题。

A*作为一种高效的、应用广的搜索算法,是我们所必须掌握的。


定义:

让我们先看看A*算法的定义:
A*(A-Star)算法是静态路网中求解最短路径的最有效的搜索算法之一,也是解决许多搜索问题的有效算法。

中的距离估算值与实际值越接近,最终搜索速度越快。


经典例题:

对于上面的定义,一些没有接触过A*的人可能会有些懵逼。没关系,我们先不管上面的定义,先来看一道例题:

如图一,绿色为A点,红色为B点,蓝色为围墙,一个方格为一个点。

我们要求A点到B点的最短路径,一个点可以走到它八个方向上与它相连的点,但不能穿过围墙。

图一)


A*算法操作模拟:

接下来,我们将用A*算法模拟上面这道例题,看完后,你基本就可以理解A*算法了。

从起点A开始走,先把A点加入open list(开放列表)中,open list中的点表示你接下来可能会经过这些点(也可

能不会经过),现在open list中只有一个点,它就是起点A。


查看与起点A相连的点(围墙除外),把其中可到达的点加入open list中,并把起点A设为这些点的父亲。


把起点A从open list中移除,加入到close list(封闭列表)中,close list中的每个点都是不需要再关注的。


下一步,我们需要从open list中选一个点,按上面描述的一样重复前面的操作。

但要选哪个点呢?选具有最小F值的那个点。

那么,F表示什么呢?请看下面。


估价函数:

对于每个状态,都有一个对应的F值。

F表示从初始状态经由当前状态到目标状态的代价估计,我们称之为估价函数。

很显然,F=G+H;

其中G表示初始状态到当前状态的实际代价。

H表示当前状态移动到目标状态的估计成本。


上面的内容听起来有点公式化,我们还是拿之前那道例题来说明吧。

在例题中,F表示从起点A经由当前点再到终点B的代价估计。

G表示从起点A到当前点的实际代价。

H表示当前点到终点B的估计成本。


有人可能会问,为什么H不能也像G那样表示实际代价呢?

很简单,我们又没有走过一条从当前点到终点B的实际路径,怎么可能知道实际代价呢?


我们来讲讲G和H怎么求。

G可以由当前点的父亲的G值递推而来。

H的话呢,你先预处理出每个点到终点B的估计距离,H就是当前点的该值。

如何求一个状态到终点状态的估计距离,要视情况而定。

在这里,我们可以假设每个点到终点B的估计距离是该点到终点B的忽略围墙的最短路。


但是,有一点要注意的是,H的大小很大程度上影响了答案与运行时间,选择估计方式要慎重。

比如H不能大于实际距离,否则答案十有八九会错。

H也不能太小,否则运行时间就和普通搜索没啥区别了。


同时,我们还要考虑计算H的时间复杂度。

像我刚才令H等于该点到终点B的忽略围墙的最短路,但很多时候,时限是不够我们求每个点到终点的最短路的。

这时,我们就可以考虑求欧几里得距离之类的。


A*算法操作模拟:

接下来,让我们继续回到上面例题的A*算法操作模拟。


上面,我们选中了一个具有最小F值的点,把它加入到close list里面,把与它相连的的点(围墙与已经在close list中

的点除外)加入open list中,并把它设为它们的父亲。

如果有与它相连的点已经在open list里面了,则判断这条路径是否更优,也就是说经由我们选中的点的G值是否

比原本的G值更小,是则把那个点的父亲设为我们选中的点,并更新那个点的G和F。否则不做任何操作。


接下来,我们将不断重复这个过程,直到我们把终点也加入了open list中,答案就为终点的G值。


归纳:

下面,我们来归纳一下A*算法的步骤。

1° 把起点加入open list

2° 从open list中选一个F值最小的,把其移出open list,加入close list

3° 把与选中的点相连的能到达的且不在close list的点加入open list,若其已在open list中则判断G值能否更新。

4° 重复2°到3°的过程,直到终点被加入到open list中,则输出终点的G值。


总结

A*的本质是一种基于贪心的搜索算法,适用于一些求最短距离、最少步数的题。


因为它每一步都选的是估计能最快到达终点的点来走,这样就通过局部最优保证整体最优,能达成两个性质:

1、最先找到的终点一定最优。

2、每一步选的点的G值一定是起点到该点的最优路线的值。


可能讲得不是很清楚,不过大家自己画一下图应该可以明白的。


最后,感谢大家的支持。

欢迎各路大佬指正本文的问题。


如果你认为本文写得好,欢迎点赞与转发(转发请标明出处与原文链接)。


原创粉丝点击