zoukankan      html  css  js  c++  java
  • 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);
    }
  • 相关阅读:
    数据库自增ID归零
    JAVA中的接口和抽象类(转)
    谈如何学习linux (转)
    如何编译安装源码包软件(转)
    每天对着电脑46小时的人必看
    JAVA错误处理大集合
    5月15号项目总结
    让程序在Windows CE系统启动时自动运行
    wince.net4.2问题
    触摸屏定位校准
  • 原文地址:https://www.cnblogs.com/IThaitian/p/2703042.html
Copyright © 2011-2022 走看看