用java实现人工智能中的A*算法求8数码问题

该博客主要展示了用Java实现人工智能中A*算法解决8数码问题的代码。定义了Eight类表示8数码状态,Queue类实现队列用于open表和closed表。最初使用Vector,因保存引用问题改用自定义队列,后来发现LinkedList也可胜任,但作业已交未修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//8数码类
class Eight{
 int e[][] = {{2,8,3},{1,6,4},{7,0,5}};   //默认的起始状态
 int faX ,faY;                                       //保存父状态中0的位置
 int f;                                                  //估价函数值
 Eight former ;           

 public Eight(){
        faX = -1;
        faY=-1;
    f=-1;
    former = null;
    }

 public Eight(Eight other){
     for(int i = 0; i<3; i++)
            for(int j=0 ;j<3; j++){
              e[i][j] = other.e[i][j];
            }
        faX = other.faX;
        faY = other.faY;
        f = other.f;
        former = other.former;
 }

 public void print()
 {
  for(int i1 = 0;i1<3;i1++)
   for(int j1=0;j1<3;j1++){
    System.out.print(e[i1][j1]);
    if(j1==2)
     System.out.println();
    }
  System.out.println();
 }

 public void listAll( Eight e ){
   while( e.former != null ){
             e.former.print();
                e = new Eight(e.former);
            }
  return ;
 }

}

class Queue extends Object{                   //队列类
 private int size = 0;
 Eight qe[] = new Eight[20];

 public void print(){
  for(int i=0;i<size;i++)
   qe[i].print();
 }

 public void addElement(Eight e){
  qe[size] = e;
  size++;
 }

 public boolean contains(Eight e){
  if( size == 0 )
   return false;
  else{
   for(int i=0;i<size;i++){
    if(qe[i].equals(e))
     return true;
   }
  }
  return false;
 }

 public boolean isEmpty(){
  if (size == 0) {
   return true;
  }
  else return false;
 }

 public Eight elementAt(int index){

  return qe[index];
 }

 public void setElementAt( Eight e,int index ){

  qe[index] = e;
 }

 public int size(){
  return size;
 }

 public int indexOf (Eight e) {
  for (int i = 0; i < size; i++){
   if (qe[i].equals( e ))
    return i;
  }
  return -1;
 }

 public void removeFirst( ){
  for(int i=0;i<size;i++){
   qe[i] = qe[i+1];
  }
        size--;
 }

 public void remove( Eight e ){
  for( int i = 0; i < size; i++ ){
   if( qe[i].equals( e ))
    qe[i] = null;
  }
        size--;
 }


 public void removeAllElements(){
  for (int i = 0; i < size; i++){
   qe[i] = null;
  }
        size = 0;
 }

}

//算法实现类
public class Asearch{
 static int dest[][] = {{1,2,3},{8,0,4},{7,6,5}};

    static void Swap(Eight ee,int i,int j,int m,int n){
     int temp;
        temp = ee.e[i][j];
        ee.e[i][j] = ee.e[m][n];
        ee.e[m][n] = temp;
 }


 static int compare(Eight a){
  int h =0,i,j;
  for(i=0;i<3;i++)
   for(j=0;j<3;j++){
    if(a.e[i][j]!=dest[i][j])
     h++;
   }
  return h;
 }
 
 //生成子状态
 static Queue born(Eight e){
  int m=1,n=1,i=0,j=0;
  boolean flag = true;
  Queue sons = new Queue();
  for(i=0;i<3&&flag;i++)
   for(j=0;j<3&&flag;j++){
    if(e.e[i][j]==0){
     flag=false;
     break;
    }
   }
  i--;
  if(i-1>=0){
         m=i-1;
            if(m!=e.faX){
             Swap(e,m,j,i,j);
                //e.print();

                Eight son1 = new Eight(e);
    son1.faX = i;
    son1.faY = j;
    son1.former = e;
                sons.addElement(son1);
             Swap(e,i,j,m,j);

        }
  }
  if(i+1<3){
         m=i+1;
            if(m!=e.faX){
             Swap(e,m,j,i,j);
                //e.print();
             Eight son2 = new Eight(e);
             son2.faX = i;
    son2.faY = j;
    son2.former = e;
                sons.addElement(son2);
                Swap(e,i,j,m,j);
        }

  }
  if(j-1>=0){
   n=j-1;
   if(n!=e.faY){
    Swap(e,i,n,i,j);
    //e.print();
    Eight son3 = new Eight(e);
    son3.faX = i;
    son3.faY = j;
    son3.former = e;
    sons.addElement(son3);
         Swap(e,i,j,i,n);
        }

  }
  if(j+1<3){
   n=j+1;
   if(n!=e.faY){
    Swap(e,i,n,i,j);
    //e.print();
             Eight son4 = new Eight(e);
             son4.faX = i;
    son4.faY = j;
    son4.former = e;
    sons.addElement(son4);
         Swap(e,i,j,i,n);
        }

  }
  return sons;
 }
 public static void main(String[] args){
  
  int depth=0;                          //深度
  Eight n = new Eight() ;
  Eight temp1 = new Eight() , temp2 = new Eight() ;
  //open表
  Queue open = new Queue();
  //closed表
  Queue closed = new Queue();
  //保存子状态的表
  Queue son = new Queue();
  open.addElement(n);

  while(!open.isEmpty()){
   n= open.elementAt(0);
   open.removeFirst( );
   if(compare(n)==0){
    n.listAll(n);
    System.out.println("Success!");
    return;
   }
   son = born(n);
   depth++;
   int count = son.size();
   if(count==0)
             continue;
   else for(int t=0;t<count;t++){
    temp1 = son.elementAt(t);
    if(!open.contains(temp1)&&!closed.contains(temp1)){
     temp1.f = depth + compare(temp1);
     open.addElement(temp1);
    }
    else if(open.contains(temp1)){
     temp1.f = depth + compare(temp1);
     int pos = open.indexOf(son.elementAt(t));
     temp2 = open.elementAt(pos);
     if(temp1.f<temp2.f){
      open.setElementAt(temp1,pos);
     }
    }
    else if(closed.contains(temp1)){
                 temp1.f = depth + compare(temp1);
                 int pos = closed.indexOf(temp1);
                 temp2 = closed.elementAt(pos);
                    if( temp1.f<temp2.f ){
                     closed.remove(son.elementAt(t));
                        open.addElement(temp1);
                    }
    }
   }//end for
            closed.addElement(n);
            for(int i=open.size()-1;i>0;i--)
                for(int j=0;j<i;j++){
                    temp1 = (Eight)open.elementAt(j);
                    temp2 = (Eight)open.elementAt(j+1);
                    if(temp1.f>temp2.f){
                     Eight tq=new Eight();
                        tq = open.elementAt(j);
                        open.setElementAt(open.elementAt(j+1),j);
                        open.setElementAt(tq,j+1);
                     }
             }
  }//end while
  
  System.out.println("Fail!");
        return;
 }//end main
}

这个程序是实现人工智能中的A*算法,照着书上的算法做的。Queue类是自己写的一个队列类,用来实现open表和closed表。原来用Vector做的,但后来发现Vector中保存的只是引用,生成子状态后表中的状态也跟着变了,只好自己实现一个队列类。现在知道还有个LinkedList类可以胜任这项工作,不过作业都交了,我也懒得改了!

include using namespace std; struct node{ int nodesun[4][4]; int pre; //上一步在队列中的位置 int flag ; //步数标识,表示当前的步数为有效的 int value; //与目标的差距 int x,y; //空格坐标 }queue[1000]; //移动方向数组 int zx[4]={-1,0,1,0}; int zy[4]={0,-1,0,1}; //当前步数 int top; int desti[4][4];//目标状态 int detect(struct node *p)//检查是否找到 {int i,j; for(i=1;i<4;i++) for(j=1;jnodesun[i][j]!=desti[i][j]) return 0; return 1; } //打印 void printlj() {int tempt; int i,j; tempt=top; while(tempt!=0) { for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<queue[tempt].nodesun[i][j]; if(j==3) cout<<" "<<endl; } tempt=queue[tempt].pre; } } //现在状态与目标状态有多少个不同位置 int VALUE(struct node *p) {int count=0; int i,j; for(i=1;i<4;i++) for(j=1;jnodesun[i][j]!=desti[i][j]) count++; return count; } void main() { //初始化 int i,j,m,n,f; int min=10; int temp,find=0,minnumber; top=1; for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<"请输入第"<<i<<"行"<<"第"<<j<<"列的值"<>temp; queue[1].nodesun[i][j]=temp; } cout<<"请输入初始状态的空格的位置(行)"<>temp; queue[1].x=temp; cout<<"请输入初始状态的空格的位置(列)"<>temp; queue[1].y=temp; queue[1].value=VALUE(&queue[1]); queue[1].pre=0; //上一步在队列中的位置 queue[1].flag=0; //目标状态 for(i=1;i<4;i++) for(j=1;j<4;j++) {cout<<"请输入目标状态第"<<i<<"行"<<"第"<<j<<"列的值"<>temp; desti[i][j]=temp; } //根据估价函数 while(!find&&top>0) { for(i=1;i<=top;i++) //////////////////////////////////////////// //min为上一图中与目标图有多少个元素不相同,queue[i]为当前图与目标图有多少个元素不相同通过这两个数的比较,就可以得出当前图较之上一图向目标图接近同时把当前的i记录下来进行下一步比较 {if(queue[i].value<min&&queue[i].flag==0) {minnumber=i;// min=queue[i].value; //还有多少不同的位数 } } queue[minnumber].flag=1; //表示此位有效 ////////////////////////////////////// // for(f=0;f=1&&i=1&&j<=3) {top++; ///////////////////////////////////////////// //位置交换 queue[top]=queue[minnumber]; queue[top].nodesun[m][n]=queue[minnumber].nodesun[i][j]; queue[top].nodesun[i][j]=0; /////////////////////////////////////// //空格移动方向 queue[top].x=i; queue[top].y=j; /////////////////////////////////////// queue[top].pre=minnumber; //上一步在队列中的位置 queue[top].value=VALUE(&queue[top]); //有多少位与目标不同 queue[top].flag=0; //标识位初始化 if(detect(&queue[top])) //检查是否为目标 {printlj(); //打印 find=1; //设找到标识位 break; } } } } }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值