A*算法

这两天学习了A*算法,总结记录一下,方便以后学习复习。(写到一半忽然崩掉,,,心态炸了)

A*算法

要了解A*算法,首先需要了解什么是启发式算法:启发式算法即一种在基于经验和预测,通过启发函数预测当前实例的成本,从而找到最优实例的方法,其算法效率与启发函数息息相关,启发函数越是接近真实值,那么算法的效率就越高。

A*算法,A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。A*算法通过启发函数计算到各个节点的估算成本,依次取其中成本最小的节点,最终能够找到最优路径。A*算法的启发函数为:F=G+H

F:即对当前路径的估算成本。

G:即从起点到当前节点的路径距离或是成本代价。

H:即从当前节点到目标节点的估算成本,,可采用曼哈顿距离、切比雪夫距离和欧几里距离等(一般采用曼哈顿距离)。

A*算法的实现

A*算法的实现如下:从起点开始,搜索能够从起点到达的所有结点,并计算各个节点的估算成本F,然后将其全部放入open表中(为了方便后续找到最优路径,应该维护一个有序表,能够方便找到其最优节点),再选取其中估算成本F最小的节点,从open表中移入到close表中去。然后再搜索该节点周围的可到达节点,计算其估算成本F并放入open表中,选取最佳节点移入close表中,一直重复该操作直到将目标节点放入到close表中,然后通过目标节点逆推,依次找到其“父节点”找出最优路径。

具体实现步骤如下:(图片来源于网络)

 假设每个网格的水平距离为10,对角距离为14,则当前节点的F计算如下:

G=父节点G+10(或14)

H=(当前节点到目标节点的横向距离+纵向距离)*10(即(|x-x0|+|y-y0|)*10,(x,y)为当前坐标,(x0,y0)为目标坐标)

F=G+H

如下图:

image001.jpg

 

  1. 为方便后续找到目标节点后逆推出最优路径,应该为每个节点设置一个“父节点”,即当前路径的上一个节点,如图:

    image002.jpg

    如上图所示,每个节点都有一个指向起点的箭头,即其“父节点”
  2. 从起点开始,将起点放入open表中,此时open表中只有起点,将起点放入到close表中
  3. 搜索起点周围可到达的节点(假设可以走对角),利用启发函数F=G+H计算路径成本F,其中G为从起点到当前节点的路径距离,即当前路径下其父节点的G加上一步的距离;H为当前节点到目标节点的估算成本,即曼哈顿距离。

    如上图,起点右侧的方块,其父节点为起点,所以G=0+10=10,H为其到目标节点的曼哈顿距离,即[(3-3)+(6-3)]*10=30,F=G+H=40 。同理,起点右下侧的节点,G=0+14=14,H=[(4-3)+(6-3)]*10=40,F=G+H=54 。求出起点周围所有8个节点的F。
  4. 将所有节点按序放入open表中,选取其中的最优节点即F值最小的节点,移入close表中,如下图:

    如图,当前的最优节点为起点右侧节点,其F为40,将其从open表移入close表中,高亮显示
  5. 搜索当前选择节点可到达节点,计算其F,由图易知,其可到达节点均已经放入open表,此时,我们通过再次计算该路径下的节点的G值判断路径是否可改善,如果当前路径下的G值小于open表中G值说明路径有所改善,改变open表中的节点的值,否则不做改变,直接选取下一个最优节点。如当前选中节点的上一节点(即起点的右上),在当前路径下G=10+10=20,大于open表中的原有值G=10,因此不做改动。同理,计算其他节点,比较是否需要更新open表。
  6. 通过计算,发现没有可改善节点,直接选取open表中的最优节点,此时发现在当前open表中存在多个最小值54,可任选最小节点(会找出不同的最优路径),我们选取当前节点的下方节点,重复上述步骤5,如下图:

  7. 重复上述步骤,直到搜索目标节点并移入到close表中,如下图:

  8. 从目标节点开始逆推其父节点,找出最优路径,即从目标节点开始通过箭头找出一条到起点的路径,如下图:

 

 至此,我们就找出了当前情况下的一条最优路径。

A*算法的代码实现

代码具体实现如下述步骤:

  1. 实现open表,close表,节点等数据结构。
  2. 将起点放入open表
  3. 选取open表中的最优节点,移入close表
  4. 搜索并计算当前节点的可到达节点的估算成本F,并有序放入open表中。如果节点在open表中原来就存在,比较当前路径下计算出来的G和open表中的G,如果小于open表中的G值,则更新open表,否则不做改变。
  5. 重复上述3、4步骤,直到将目标节点放入到close表。
  6. 从目标节点开始,通过每个节点记录下个父节点,逆推出最优路径。

总结

A*算法主要是用于规划最优路径,是一种很高效的算法且能够保证找到最短路径,其效率与启发函数相关,通过改变启发函数我们也可以考虑到更多中情况,如地形因素,时间因素,多路径等。 

你可能感兴趣的:(算法)