八数码难题(下):启发式搜索【python实现】

关于上篇八数码问题(Eight Puzzle Problem)的简单介绍和BFS解法(无信息搜索)在上一篇已经有过阐述:八数码难题(上):无信息搜索【python实现】什么是启发式搜索?启发式搜索(Heuristic Search)也被称为有信息搜索。和无信息搜索相反,这类的搜索算法的决策依赖于一定的信息,利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的。贪心最优搜索和A/A*搜索都是启发式搜索。贪心(GBFS):策略:拓展看起来离目标最近的节点估价函数f(n) =
摘要由CSDN通过智能技术生成

关于上篇

八数码问题(Eight Puzzle Problem)的简单介绍和BFS解法(无信息搜索)在上一篇已经有过阐述:八数码难题(上):无信息搜索【python实现】


什么是启发式搜索?

启发式搜索(Heuristic Search)也被称为有信息搜索。和无信息搜索相反,这类的搜索算法的决策依赖于一定的信息,利用问题拥有的启发信息来引导搜索,达到减少搜索范围、降低问题复杂度的目的。贪心最优搜索和A/A*搜索都是启发式搜索。

贪心(GBFS):

  • 策略:拓展看起来离目标最近的节点
  • 估价函数f(n) = h(n),估计节点n到目标的代价
  • 最坏情况:退化为DFS
  • 完备性:不具有
  • 时间复杂度/空间复杂度:O(b^m)

A* 搜索(A* Search):

  • 策略:避免扩展消耗很大的路径
  • 估价函数f(n) = g(n) + h(n),走过+剩余
  • 估计代价h(n)应小于实际,否则会退化到A算法
  • 可纳性/准确性:h(n) <= h*(n) ,若大于可能会错过最优解
  • 最优性:当h(n)可纳,A*为最优搜索树算法
  • 一致性/单调性(图搜索):h(n) <= cost(n’) + h(n’),即代价增加
  • 优势性:可纳启发式函数h1(n) < h2(n),h2优于h1

A* (pronounced “A-star”) is a graph traversal and path search algorithm, which is often used in many fields of computer science due to its completeness, optimality, and optimal efficiency. One major practical drawback is its O(bd) space complexity, as it stores all generated nodes in memory. Thus, in practical travel-routing systems, it is generally outperformed by algorithms which can pre-process the graph to attain better performance, as well as memory-bounded approaches; however, A* is still the best solution in many cases.

Peter Hart, Nils Nilsson and Bertram Raphael of Stanford Research Institute (now SRI International) first published the algorithm in 1968. It can be seen as an extension of Dijkstra’s algorithm. A* achieves better performance by using heuristics to guide its search.

贪心搜索的局限性:
贪心的局限性
在这里插入图片描述

A*搜索(对比Dijkstra和GBFS):
在这里插入图片描述

A*搜索解八数码问题

在开始之前,了解一下曼哈顿距离(Manhattan Distance):

  • 曼哈顿距离又称为街区距离,度量两个点在标准坐标系上的绝对轴距总和
  • d(i,j) = |xi-xj| + |yi-yj|

在这里插入图片描述

  1. 在整体代码的设计思路框架上,我们沿用上篇所讲的BFS方法。
  2. 使用queue库中的PriorityQueue实现优先队列。
import queue
# 这里只是解释用法
q = queue.PriorityQueue()
q.put() # 在优先队列中添加元素,添加后的元素会自动排列(默认升序)
q.get() # 取出队头元素(即最小值)
  1. 搭建框架。(这一段不明白的可以看看上篇)
def a_star(start):
   q.put([0, start]) # 初始化优先队列
   d[start] = 0
   while q:
       t = q.get()[1] # 当队列不为空,每次取出队头
       ......
       for i in range(4): # 遍历周围四个方向
          ......
               if not d.__contains__(t
  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值