用A星算法解决八数码问题.docx
《用A星算法解决八数码问题.docx》由会员分享,可在线阅读,更多相关《用A星算法解决八数码问题.docx(11页珍藏版)》请在冰豆网上搜索。
用A星算法解决八数码问题
A*算法解决八数码问题
1问题描述
什么是八数码问题
八数码游戏包括一个3
3的棋盘,棋盘上摆放着8个数字的棋子,留下一个空位。
与空位相邻的棋子可以滑动到空位中。
游戏的目的是要达到一个特定的目标状态。
标注的形式化如下:
1
2
3
4
5
6
!
7
8
问题的搜索形式描述
状态:
状态描述了8个棋子和空位在棋盘的9个方格上的分布。
初始状态:
任何状态都可以被指定为初始状态。
操作符:
用来产生4个行动(上下左右移动)。
目标测试:
用来检测状态是否能匹配上图的目标布局。
路径费用函数:
每一步的费用为1,因此整个路径的费用是路径中的步数。
现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态。
解决方案介绍
算法思想
(
估价函数是搜索特性的一种数学表示,是指从问题树根节点到达目标节点所要耗费的全部代价的一种估算,记为f(n)。
估价函数通常由两部分组成,其数学表达式为
f(n)=g(n)+h(n)
其中f(n)是节点n从初始点到目标点的估价函数,g(n)是在状态空间中从初始节点到n节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。
保证找到最短路径(最优解)的条件,关键在于估价函数h(n)的选取。
估价值h(n)<=n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。
但能得到最优解。
如果估价值>实际值,搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
搜索中利用启发式信息,对当前未扩展结点根据设定的估价函数值选取离目标最近的结点进行扩展,从而缩小搜索空间,更快的得到最优解,提高效率。
启发函数
进一步考虑当前结点与目标结点的距离信息,令启发函数h(n)为当前8个数字位与目标结点对应数字位距离和(不考虑中间路径),且对于目标状态有h(t)=0,对于结点m和n(n是m的子结点)有h(m)–h(n)<=1=Cost(m,n)满足单调限制条件。
2算法介绍
A*算法的一般介绍
A*(A-Star)算法是一种静态路网中求解最短路最有
A star算法在静态路网中的应用
#
效的方法。
对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)*(dx-nx)+(dy-ny)*(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。
明显优于盲目搜索策略。
算法伪代码
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
算起点的估价值,将起点放入OPEN表。
while(OPEN!
=NULL)
{
从OPEN表中取估价值f最小的节点n;
if(n节点==目标节点)
{break;}
for(当前节点n的每个子节点X)
{
算X的估价值;
【
if(XinOPEN)
{
if(X的估价值小于OPEN表的估价值)
{把n设置为X的父亲;
更新OPEN表中的估价值;中有结点设为n1被扩展放入closed表时,n1的前驱刚好已经存储好。
下面说明closed表中任意一个结点都存储有它的前驱结点的信息,考虑closed表中任意一个结点,如果它是初始结点,它没有前驱结点,如果不是根结点,扩展该结点时它的前驱结点已经记录。
从而在closed表中形成扩展关系的树状结构。
因为只需要前驱结点的下标位置,可以用数组实现,每个结点记录整数表示的8数码格局和它的前驱结点的下标,输出路径时,根据前驱结点形成到达根结点的链条,递归输出即可。
解决结点重复扩展问题
对于一个结点有多种方式到达该结点,这样就可能多次将它加入open表中,而启发函数满足单调限制条件,后来达到该结点的路径不再是更优的,可以不予考虑。
扩展某结点时先看该结点是否已经扩展过,如果扩展过则略过。
实现的可以线形遍历closed表,但效率不高时间复杂度为O(closedSize),考虑每个结点可以用一个整数标识,用二叉平衡查找树可以得到更好的时间复杂度O(log(closedSize)),程序中用基于红黑树思想的set实现。
实验结果
输入数据(0表示空格)
步数
扩展结点数
<
生成结点数
搜索用时(毫秒)
312405678
2
5
11
0
312475680
4
17
28
{
0
372815460
无解
123456780
22
7943
12019
2266
!
参考文献
王勋,凌云,费玉莲.2005.人工智能导论.北京:
科学出版社
广树建,王钰淇.2008.新编C/C++程序设计教程.广州:
华南理工大学出版社
王文杰,史忠植.2007.人工智能原理辅导与练习.北京:
清华大学出版社出
附录—源代码及其注释
源代码及测试数据
/*
算法:
A*
是否最优解:
是
启发函数:
每一个数字位与目标中该数字位的距离,满足单调限制。
说明:
A*算法是启发式搜索算法,搜索时充分利用当前状态距目标距离远近的启发信息,选取当前未扩展结点中估价函数最小的进行扩展,生成结点数少,搜索空间较小,实现稍复杂,
备注:
程序未对输入数据进行检查
*/
#pragmawarning(disable:
4786)
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
/*
item记录搜索空间中一个结点
state记录用整数形式表示的8数码格局
blank记录当前空格位置,主要用于程序优化,扩展时可不必在寻找空格位置
g,h 对应g(n),h(n)
pre 记录当前结点由哪个结点扩展而来
*/
structitem
{
intstate;
intblank;
intg;
inth;
intpre;
};
constintMAXSTEPS=100000;
constintMAXCHAR=100;
charbuf[MAXCHAR][MAXCHAR];
irst);
puts("");
return;
}
path(closed[index].second);
pr(closed[index].first);
puts("");
++steps;
}
intmain()
{
unsignedintt1=clock();
freopen("","r",stdin);
freopen("","w",stdout);
setstates;
chartmp[100];
inti,x,y,a,b,nx,ny,end,next,index,kase=0;
pairstart,target;
itemhead;
tate=;
open[0].h =calculate,;
open[0].blank=;
open[0].pre =-1;
open[0].g =0;
index=0;
;
irst =open[0].state;
closed[index].second=open[0].pre;
re =index;
open[end].blank=b;
open[end].state=next;
open[end].h =calculate(next,;
open[end].g =+1;
++end;
push_heap(open,open+end,cmp());
}
}
}
}
if(end<=0)
puts("Nosolution");
else
{
printf("Numofsteps:
%d\n",steps);
printf("Numofexpanded:
%d\n",index);
printf("Numofgenerated:
%d\n",index+end);
printf("Timeconsumed:
%d\n\n",clock()-t2);
}
();
steps=0;
}
printf("Totaltimeconsumed:
%d\n",clock()-t1);
return0;
}
(
系统中间及最终输出结果
输入312405678
输入312475680
输入372815460
输入123456780