题目2:隐式图的搜索问题(A*算法解决八数码)

本文介绍了如何使用A*算法解决八数码游戏。通过状态压缩表示棋盘状态,利用估价函数f(n)=g(n)+h(n)进行启发式搜索,其中g(n)表示实际代价,h(n)表示目标状态的接近程度。A*算法确保找到最优解,并在搜索过程中每个状态只扩展一次。文章还探讨了BFS算法的不足,以及A*算法如何克服这些问题。
摘要由CSDN通过智能技术生成

声明

题目要求

看过这次实验要求之后在这里插入图片描述

总结:利用A*来解决八数码问题,状态很好找,每次移动空格就会形成一种新的状态,

何为八数码?

八数码游戏包括一个3X3的棋盘,棋盘上摆放着8个数字的棋子,留下一个空位。与空位相邻的棋子可以滑动到空位中。游戏的目的是要达到一个特定的目标状态。标注的形式化如下(举例):

2 3
1 8 4
7 6 5

(初始状态)

1 2 3
8 4
7 6 5

(目标状态)

状态如何表示

  1. 每个状态都用3*3的数组表示,但是BFS中需要入队出队,比较麻烦而且空间占用较大
  2. 状态压缩,采用一个整数保存状态的数字序列,例如状态1表示为203184765,状态2表示为123804765

所需知识

优先队列BFS算法,因为A*算法就是带有估价函数的优先队列BFS

导出所需知识

优先队列BFS算法缺陷

该算法维护了一个优先队列(二叉堆),不断从堆中取出“当前代价最小”的状态(堆顶)去进行扩展。但是它得到只是初态到该状态的最小代价并没有去考虑从该状态出发到目标状态的情况)

举例说明:
如果给定一个“目标状态”,需要求出从初态到目标状态的最小代价,优先队列BFS显然不行。因为一个状态的当前代价最小,只能说明从起始状态到该状态的代价很小,而在未来的探索中,从该状态到目标状态可能会花费很大的代价另外一些状态虽然当前代价略大,但是未来到目标状态的代价可能会很小,于是从起始状态到目标状态的总代价反而更优。

A*搜索算法

于是,我们为了解决上面的问题:可以对未来可能产生的代码进行预估。详细地讲,我们去设计一个**“估价函数”**,以任意状态为输入,计算出从该状态到目标状态所需代价的估计值。在搜索之中,仍然维护了一个堆,不断从堆中取出“当前代价+未来估价”最小的状态来进行扩展。

为了保证第一次从堆中取出目标状态时得到的就是最优解,我们设计的估价函数需要满足一个基本准则:

设当前状态state到目标状态所需代价的估计值为f(state);设在未来的探索中,实际求出的从当前状态state到目标状态的最小代价为g(state)
对于任意的state,应该有f(state)<=g(state)

也就是说,估价函数的估值不能大于未来实际代价,估价比实际代价更优。估价函数f(n)=g(n)+h(n)

总结:

这种带有估价函数的优先队列BFS就成为A* 算法。只要保证对于任意状态state,都有f(state)<=g(state),A* 算法就一定能在目标状态第一次从堆中被取出时得到最优解,并且在搜索过程中每个状态只需要扩展一次(之后再被取出就可以直接忽略 )。估价f(state)越准确,越接近g(state),A*算法的效率越高。如果估价始终为0,就等于普通的优先队列BFS。

实际操作

搜索过程描述

A算法又称为启发式搜索算法。对启发式搜索算法,又可根据搜索过程中选择扩展节点的范围,将其分为全局择优搜索算法局部择优搜索算法

在全局择优搜索中,每当需要扩展节点时,总是从 Open 表的所有节点中选择一个估价函数值最小的节点进行扩展。其搜索过程可能描述如下:

  1. 把初始节点 S0 放入 Open 表中, f(S0)=g(S0)+h(S0)
  2. 如果 Open 表为空,则问题无解,失败退出;
  3. 把 Open 表的第一个节点取出放入 Closed 表,并记该节点为 n ;
  4. 考察节点 n 是否为目标节点。若是,则找到了问题的解,成功退出;
  5. 若节点 n 不可扩展,则转到第 (2) 步;
  6. 扩展节点 n ,生成子节点 ni ( i =1,2, …… ) ,计算每一个子节点的估价值 f( ni ) ( i =1,2, …… ) ,并为每一个子节点设置指向父节点的指针,然后将这些子节点放入 Open 表中;
  7. 根据各节点的估价函数值,对 Open 表中的全部节点按从小到大的顺序重新进行排序;
  8. 转第 (2) 步。

这里采用的启发式策略为:f(n) = g(n) + h(n),其中g(n)为从初始节点到当前节点的步数(层数),h(n)为 当前节点 “不在位 ”的方块数(也就是说不在位的方块数越少,那么临目标状态越近)例如下图中的h(n)=5,有的讲解的是不包含空格,我这里是包含了的,经测试只要前后标准一致,包不包含空格都一样。
g(n)为已经消耗的实际代价,即已经走了的步数
h(n)为预测路径,即还有几个数字待走

在这里插入图片描述
h(n)=5

启发式策略工作工程:红圈数字表示扩展顺序

在这里插入图片描述

代码实现

Map+BFS+A*

#include<cstdio>
#include<queue>
#include<map>
using namespace std;
char arr[10], brr[10] = "123804765";
struct node {
   
	int num, step, cost, zeroPos;
	bool operator<(const node& a)const {
   
		return cost > a.cost;
	}
	node(int n, int s, int p) {
   
		num = n, step = s, zeroPos = p;
		setCost();
	}
	void setCost() {
   
		char a[10];
		int c = 0;
		sprintf(a, "%09d&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值