【算法】A*算法与启发函数

写这篇是因为看到国外一篇讲的巨好的关于A*算法的文章——Introduction to A*。图文并茂,而且讲了一些A*算法的来龙去脉,有些观点也醍醐灌顶啊,所以赶紧来总结一下。

A*算法为什么叫这个名

这个从wiki上看来的,一开始是57年提出的Dijkstra算法,然后64年Nils Nilsson提出了A1算法,是一个启发式搜索算法,而后又被改进成为A2算法,直到68年,被Peter E. Hart改进成为A*算法,为什么叫A*呢,因为原作者借鉴了统计学方面的一个*上标,在统计学中,一个变量加上 * 表示这个变量的最优解,所以作者认为他们是最优解,是前人(A算法)的集大成者,所以叫A*。

BFS和Dijkstra算法

要讲A*算法就必须去讲Dijkstra算法,因为Dijkstra算法可以看成A*算法的特例。而BFS又可以看成Dijkstra的特例,
对于BFS算法,python代码如下:

frontier = Queue()
frontier.put(start)
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal: 
      break           

   for next in graph.neighbors(current):
      if next not in came_from:
         frontier.put(next)
         came_from[next] = current

对于Dijkstra算法,python代码如下:

frontier = PriorityQueue()   #这个地方用优先队列了
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break

   for next in graph.neighbors(current):
      new_cost = cost_so_far[current] + graph.cost(current, next)
      if next not in cost_so_far or new_cost < cost_so_far[next]:
         cost_so_far[next] = new_cost
         priority = new_cost
         frontier.put(next, priority)
         came_from[next] = current

Dijkstra算法是一个贪心算法/也可以看成动规。其是每次都找离起点最近的点
Dijkstra算法保证能得到最优解,但是扫描的区域会比较的大。
这里写图片描述

Dijkstra算法搜索的空间太大了,能不能利用网格图的一些特点来简化搜索呢?想到了贪心算法。
贪心搜索算法,是每次找离终点距离最近的点
另外如何定义这个距离呢,一般网格图是用曼哈顿距离来定义的。即两个点之间坐标差的绝对值之和。

def heuristic(a, b):
   # Manhattan distance on a square grid
   return abs(a.x - b.x) + abs(a.y - b.y)

frontier = PriorityQueue()
frontier.put(start, 0)
came_from = {}
came_from[start] = None

while not frontier.empty():
   current = frontier.get()

   if current == goal:
      break

   for next in graph.neighbors(current):
      if next not in came_from:
         priority = heuristic(goal, next)
         frontier.put(next, priority)
         came_from[next] = current

这里写图片描述

启发函数的性质

那么能不能综合上面Dijkstra算法得到最优解和贪心算法速度快的特点,有更好的办法呢?
注意一下这个地方,Dijkstra算法是适用于任何图算法找最短距离均可的,但是用到启发式算法的话,大部分情况下会是一个方格图,因为只有方格图才能比较好的估算从当前点到终点的距离
那么我们可以先定义一个估算函数

f(
  • 11
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值