算法学习笔记1 -- A* 算法

1,概述

A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

A* 算法是BFS算法的一种变形。

A*算法在搜索的过程中, 会根据一定的启发函数选择一个合适的节点进行下一步的搜索,具体描述如下:

公式表示为: f(n)=g(n)+h(n),
其中 f(n) 是从初始点经由节点n到目标点的估价函数,
g(n) 是在状态空间中从初始节点到n节点的实际代价,
h(n) 是从n到目标节点最佳路径的估计代价。
保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:
如果 估价值h(n)<=h*(n), 其中h*(n)表示n几点到目标节点的距离实际最短距离,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解
如果 估价值h(n)>h*(n), 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解

 A*算法与广度、深度优先和Dijkstra 算法的联系就在于:当g(n)=0时,该算法类似于DFS,当h(n)=0时,该算法类似于BFS。且同时,如果h(n)为0,只需求出g(n),即求出起点到任意顶点n的最短路径,则转化为单源最短路径问题,即Dijkstra算法。这一点,可以通过上面的A*搜索树的具体过程中将h(n)设为0或将g(n)设为0而得到。


2,算法步骤

   1,把起始节点添加到open queue。
   2,重复如下的工作:
      a) 寻找open queue中f(n)值最低的节点。我们称它为当前节点。
      b) 把当前节点移动到close queue
      c) 对当前节点的每个相邻节点
          * 如果它已经在close queue中,略过它。反之如下。
          * 如果它不在open queue中,把它添加进去。把节点作为这一节点的父节点。记录这一格的f(n), g(n), 和h(n)值。
          * 如果它已经在open queue中,用当前节点的g(n)值为参考检查新的路径是否更好。更低的g(n)值意味着更好的路径。如果是这样,就把这一节点的父节点改成当前节点,并且重新计算这一节点的g(n)和f(n)值。如果保持open queu按f(n)值排序,改变之后要重新对open queue排序。

      d) 停止,当你
          * 把目标节点添加进了close queu,这时候路径被找到,或者
          * 没有找到目标节点,open queue已经空了。这时候,路径不存在。
   3.保存路径。从目标节点开始,沿着每一节点的父节点移动直到回到起始节点。这就是你的路径。


3,证明h(n)<=h*(n) 时得到的是最优解

证明:

设问题的起点为S, 目标节点为D, 问题的最优解为M

如果问题有可行解,由A*算法搜索过程可知(A*会搜索所有路径,直到找到可行解),必存在一点n' 使得h(n')=h*(n'), 即n'和D之间是联通的,也即n'为算法路径中的D点的前一个节点。

假设当h(n)<=h*(n)时A*算法没能得到最优解,仅得到一个可行解K

此时在算法的最后一步会有如下的数据分布:

open queue:D, n1, n2,,,, n^ ,,,,,   (其中f(D) < f(n1) < f(n2) ,,,,< f(n^) <,,,,,)

close queue:n3, n4,,,,,,

由于K不是最优解,则必存在最优解M中的节点n^且f(n^) > f(D) = K (不然根据A*算法,不会选择D为下一个搜索节点)

f(n^ )= g(n^)+h(n^) <= g(n^)+h*(n^) = M

<==>

f(n^) <= M, 由于 f(n^) > f(D) = K

<==>

M > K

与M是最小解矛盾,故原假设当h(n)<=h*(n)时A*算法没能得到最优解不成立

即当h(n)<=h*(n)时A*算法能得到最优解



参考文章:

http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx

http://baike.baidu.com/view/7850.htm

http://blog.csdn.net/v_JULY_v/article/details/6238029

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值