#include<stdio.h> typedef struct { int parent; int index; int Grid[9]; int H;//启发函数值 }State; State S,T;//起始态,目标态 State OPEN[2000];//队列-----考察已考察过的状态 State CLOSE[2000];//--------存储待考察的状态 int OPhead=0,OPtail=0,openlen=2000; int CLhead=0,CLtail=0,closelen=2000; void readdata(); void init(); int search(); int Evaluate(State s); void addtoopen(State v);//将节点v加入队列 State takeoutofopen();//从OPEN表中取队头数据 void addtoclose(State v); State Swap(State v,int Epindex,int Nindex); int main() { readdata(); int flag=search(); if(flag==1)//找到了,输出CLOSE表中的考察过的状态 for(int i=CLhead;i<CLtail;i++) { printf("第%d个状态 ",i); for(int j=0;j<9;j++) printf(" %d",CLOSE[i].Grid[j]); printf("\n"); } return 0; } int search() { State u,v; while(OPhead != OPtail) { int Epindex,Nindex; u = takeoutofopen();//从队列头取数据 for(int i=0;i<9;i++) v.Grid[i]=u.Grid[i];//子节点v复制父节点u的状态 for(int k=0;k<9;k++) if(u.Grid[k]==0) Epindex=k; //记录父节点u空格位所在的位置 v.parent =u.index ; v.index =u.index+1; //四个方向搜索----暂时不考虑去除父节点的 //空格向上移 Nindex=(Epindex/3-1)*3+Epindex%3;//计算待移动的数据所在的位置 if(Epindex/3-1>=0) { v=Swap(v,Epindex,Nindex); v.H=Evaluate(v); if(v.H==0) return 1; addtoopen(v);//将当前状态节点加入到OPEN表 } //空格向下移 Nindex=(Epindex/3+1)*3+Epindex%3; if(Epindex/3+1<3) { v=Swap(v,Epindex,Nindex); v.H=Evaluate(v); if(v.H==0) return 1; addtoopen(v); } //空格向左移 Nindex=Epindex/3*3+(Epindex%3-1); if(Epindex%3-1>=0) { v=Swap(v,Epindex,Nindex); v.H=Evaluate(v); if(v.H==0) return 1; addtoopen(v); } //空格向右移 Nindex=Epindex/3*3+(Epindex%3+1); if(Epindex%3+1<3) { v=Swap(v,Epindex,Nindex); v.H=Evaluate(v); if(v.H==0) return 1; addtoopen(v); } //按启发函数值对OPEN表中的元素进行排序----降序 for(int ii=OPhead;ii<OPtail;ii++) { int kk=ii; for(int jj=ii;jj<OPtail;jj++) if(OPEN[jj].H>OPEN[kk].H) kk=jj; State temp=OPEN[ii]; OPEN[ii]=OPEN[kk]; OPEN[kk]=temp; } //将u加入CLOSE表 addtoclose(v); } return 0; } State Swap(State v,int Epindex,int Nindex) { int temp=v.Grid[Epindex]; v.Grid[Epindex]=v.Grid[Nindex]; v.Grid[Nindex]=temp; return v; } State takeoutofopen()//从队列头取节点数据 { State v; v=OPEN[OPhead++]; OPhead=OPhead%openlen; return v; } void addtoopen(State v) { OPEN[OPtail++]=v; OPtail = OPtail%openlen; //走过的点状态记为1 } void addtoclose(State v) { CLOSE[CLtail++]=v; CLtail = CLtail%closelen; //走过的点状态记为1 } int Evaluate(State s)//启发式函数 { int count=0;//数列逆序值 for(int i=0;i<9;i++) { for(int j=0;j<i;j++) if(s.Grid[j]>s.Grid[i]) count++; } return count;//返回逆序值 } void readdata() { //起始态输入 S.index=0; S.parent=-1; S.Grid[0]=2; S.Grid[1]=8; S.Grid[2]=3; S.Grid[3]=1; S.Grid[4]=6; S.Grid[5]=4; S.Grid[6]=7; S.Grid[7]=0;// S.Grid[8]=5; //for(int i=0;i<9;i++) //scanf(" %d",&S.Grid[i]);//&??? S.H=Evaluate(S); //目标态输入 //////////////// addtoopen(S); }