实验要求:
3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,移动棋子从初始布局到达目标布局,求解移动步骤并输出。请设计算法,使用合适的搜索策略,在较少的空间和时间代价下找到最短路径。
A*算法
常用于求解地图中一点到另一点的最优路径,一般都是带有障碍物的路线。有点贪心的味道,不断寻找离目标最近的节点,然后结合广度优先算法搜索。
- 启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提到了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。
- 估值函数:从当前节点移动到目标节点的预估成本;这个估计就是启发式的。
- 曼哈顿距离:两点在南北方向上的距离加上在东西方向上的距离,在搜索最短距离时表示起点到终点的直线距离的直角三角形的两条边。
所需参数:
起始点start
终点goal
h_score
g_socre
f_score
开放列表open_list:存放待检查的方格,随检测点扩大
封闭列表close_list:存放不需要关注的方格
路径排序:
- F=G+H
- G(当前路径代价) = 从当前方格移动到指定方格的移动代价,沿着到达该方格而生成的路径,这里用绝对距离,即欧氏距离,但对角线使用14来简化计算;如:在起点四周一圈的节点横向或纵向的值为10,对角线为14
- H (预估代价)= 从指定的方格移动到终点的估算成本,这里使用的即是曼哈顿距离,就是横向的距离目加上纵向的距离,终点到起点的距离,横向的方格数加上纵向的方格数乘以10。
寻路历程:
- 从起点开始,将其放入open_list,
- 查看与起点相邻的方格,忽略障碍物,,将其中可走的,可到达的方格加入到open_list中
- 将起点从open_list中移除,放入close_list
- 通过计算F的值,判断与起点相邻的值最小的方块,将该方块从open_list中取出,放入close_list中(F值相同再比较H)
- 搜索与该方格相邻的方格,忽略其中在closelist中的方格和障碍物,将其全部加入到openlist中
- 把选定的方格设置为这些新加入的方格的父亲
- 如果某个相邻的方格已经在 open_list 中,则检查这条路径是否更优,也就是说经由当前方格 ( 我们选中的方格 ) 到达那个方格是否具有更小的 G 值。如果没有,不做任何操作。如果 G 值更小,则把那个方格的父亲设为当前方格 ( 我们选中的方格 ) ,然后重新计算那个方格的 F 值和 G 值。
- 选中作为父节点的即是路径,最终到达终点只需根据父节点来回寻路径
算法演示过程:https://www.bilibili.com/video/BV1Gs411Y7ut.
隐式图的搜索问题
这里根据A*算法寻找最优路径的解法,将九宫格的不同状态作为地图的节点,路径的判优采取如下方法:
F=G+H
G:当前搜索的层数
H:当前状态与最终结果相比较不同状态的格数
同时搜索方式类似BFS,不断展开。
学习参考: https://www.jianshu.com/p/8905d4927d5f.
学习参考: http://www.360doc.com/content/16/1201/12/99071_610999046.shtml.
学习参考: http://www.xinyueseo.com/algorithm/140.html.