AI_八数码

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

}

 

你可能感兴趣的:(a)