#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);
}