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

 

posted on 2012-09-25 21:42  IThinktan  阅读(177)  评论(0编辑  收藏  举报

导航