用A算法解决八数码问题.docx
- 文档编号:30618214
- 上传时间:2023-08-18
- 格式:DOCX
- 页数:11
- 大小:19.97KB
用A算法解决八数码问题.docx
《用A算法解决八数码问题.docx》由会员分享,可在线阅读,更多相关《用A算法解决八数码问题.docx(11页珍藏版)》请在冰豆网上搜索。
用A算法解决八数码问题
用A*算法解决八数码问题
一、题目:
八数码问题也称为九宫问题。
在3×3的棋盘,有八个棋子,每个棋子上标有1至8的*一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。
要解决的问题是:
任意给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
二、问题的搜索形式描述
状态:
状态描述了8个棋子和空位在棋盘的9个方格上的分布。
初始状态:
任何状态都可以被指定为初始状态。
操作符:
用来产生4个行动(上下左右移动)。
目标测试:
用来检测状态是否能匹配上图的目标布局。
路径费用函数:
每一步的费用为1,因此整个路径的费用是路径中的步数。
现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态算法介绍
三、解决方案介绍
1.A*算法的一般介绍
A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。
对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即
;
这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。
明显优于盲目搜索策略。
Astar算法在静态路网中的应用
2.算法伪代码
创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
算起点的估价值,将起点放入OPEN表。
while(OPEN!
=NULL)
{
从OPEN表中取估价值f最小的节点n;
if(n节点==目标节点)
{break;}
for(当前节点n的每个子节点*)
{
算*的估价值;
if(*inOPEN)
{
if(*的估价值小于OPEN表的估价值)
{把n设置为*的父亲;
更新OPEN表中的估价值;//取最小路径的估价值}
}
if(*inCLOSE)
{
if(*的估价值小于CLOSE表的估价值)
{把n设置为*的父亲;
更新CLOSE表中的估价值;
把*节点放入OPEN//取最小路径的估价值}
}
if(*notinboth)
{把n设置为*的父亲;
求*的估价值;
并将*插入OPEN表中;//还没有排序}
}//endfor
将n节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序;//实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//endwhile(OPEN!
=NULL)
保存路径,即从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径.
四、源程序
#include
#include
#include
usingnamespacestd;
constintROW=3;
constintCOL=3;
constintMA*DISTANCE=10000;
constintMA*NUM=10000;
intabs(inta)
{
if(a>0)returna;
elsereturn-a;
}
typedefstruct_Node{
intdigit[ROW][COL];
intdist;//距离
intdep;//深度
intinde*;//索引值
}Node;
Nodesrc,dest;
vector
boolisEmptyOfOPEN(){//判断Open表是否空
for(inti=0;i if(node_v[i].dist! =MA*NUM) returnfalse; } returntrue; } boolisEqual(intinde*,intdigit[][COL]){//判断节点是否与索引值指向的节点相同 for(inti=0;i for(intj=0;j if(node_v[inde*].digit[i][j]! =digit[i][j]) returnfalse; } returntrue; } ostream&operator<<(ostream&os,Node&node){ for(inti=0;i for(intj=0;j os< os< } returnos; } voidPrintSteps(intinde*,vector rstep_v.push_back(node_v[inde*]); inde*=node_v[inde*].inde*; while(inde*! =0){ rstep_v.push_back(node_v[inde*]); inde*=node_v[inde*].inde*; } for(inti=rstep_v.size()-1;i>=0;i--) cout<<"Step"< < } voidSwap(int&a,int&b){//交换 intt; t=a; a=b; b=t; } voidAssign(Node&node,intinde*){//获取节点 for(inti=0;i for(intj=0;j node.digit[i][j]=node_v[inde*].digit[i][j]; } intGetMinNode(){//获取启发值最小的节点 intdist=MA*NUM; intloc;//thelocationofminimizenode for(inti=0;i if(node_v[i].dist==MA*NUM) continue; elseif((node_v[i].dist+node_v[i].dep) loc=i; dist=node_v[i].dist+node_v[i].dep; } } returnloc; } boolisE*pandable(Node&node){//判断是否可扩展 for(inti=0;i if(isEqual(i,node.digit)) returnfalse; } returntrue; } intDistance(Node&node,intdigit[][COL]){//计算距离 intdistance=0; boolflag=false; for(inti=0;i for(intj=0;j for(intk=0;k for(intl=0;l if(node.digit[i][j]==digit[k][l]){ distance+=abs(i-k)+abs(j-l); flag=true; break; } else flag=false; } if(flag) break; } returndistance; } intMinDistance(inta,intb){//二者取小 return(a a: b); } voidProcessNode(intinde*){//展开节点 int*,y; boolflag; for(inti=0;i for(intj=0;j if(node_v[inde*].digit[i][j]==0){ *=i;y=j; flag=true; break; } elseflag=false; } if(flag) break; } Nodenode_up;//上移操作 Assign(node_up,inde*); intdist_up=MA*DISTANCE; if(*>0){ Swap(node_up.digit[*][y],node_up.digit[*-1][y]); if(isE*pandable(node_up)){ dist_up=Distance(node_up,dest.digit); node_up.inde*=inde*; node_up.dist=dist_up; node_up.dep=node_v[inde*].dep+1; node_v.push_back(node_up); } } Nodenode_down;//下移操作 Assign(node_down,inde*); intdist_down=MA*DISTANCE; if(*<2){ Swap(node_down.digit[*][y],node_down.digit[*+1][y]); if(isE*pandable(node_down)){ dist_down=Distance(node_down,dest.digit); node_down.inde*=inde*; node_down.dist=dist_down; node_down.dep=node_v[inde*].dep+1; node_v.push_back(node_down); } } Nodenode_left;//左移操作 Assign(node_left,inde*); intdist_left=MA*DISTANCE; if(y>0){ Swap(node_left.digit[*][y],node_left.digit[*][y-1]); if(isE*pandable(node_left)){ dist_left=Distance(node_left,dest.digit); node_left.inde*=inde*; node_left.dist=dist_left; node_left.dep=node_v[inde*].dep+1; node_v.push_back(node_left); } } Nodenode_right;//右移操作 Assign(node_right,inde*); intdist_right=MA*DISTANCE; if(y<2){ Swap(node_right.digit[*][y],node_right.digit[*][y+1]); if(isE*pandable(node_right)){ dist_right=Distance(node_right,dest.digit); node_right.inde*=inde*; node_right.dist=dist_right; node_right.dep=node_v[inde*].dep+1; node_v.push_back(node_right); } } node_v[inde*].dist=MA*NUM; } intmain(){ intnumber; cout<<"输入初始状态: "< for(inti=0;i for(intj=0;j cin>>number; src.digit[i][j]=number; } src.inde*=0; src.dep=1; cout<<"输入目标状态"< for(intm=0;m for(intn=0;n cin>>number; dest.digit[m][n]=number; } node_v.push_back(src); while (1){ if(isEmptyOfOPEN()){ cout<<"找不到解! "< return-1; } else{ intloc;//thelocationoftheminimizenode loc=GetMinNode(); if(isEqual(loc,dest.digit)){ vector cout<<"初始状态: "< cout< PrintSteps(loc,rstep_v); cout<<"成功! "< break; } else ProcessNode(loc); } } return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 解决 数码 问题