节点Node类实现
class Node
{
Scanner in=new Scanner(System.in);
int deep;
int Draw[][];
Node father;
public Node()
{
Draw=new int[3][3];
}
public void Input() //输入
{
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
Draw[i][k]=in.nextInt();
}
public void SetDeep(int deep)
{
this.deep=deep;
} //设置深度
public int G()
{
return deep;
} //获取G值
public int H(Node A) //获取H值
{
int count=0;
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
if(this.Draw[i][k]!=A.Draw[i][k])
count++;
return count;
}
public int Function(Node A)
{
return G()+H(A);
}
public Node left() //生成空格向左移动的节点
{
boolean flag=false;
Node left=new Node();
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
left.Draw[i][k]=this.Draw[i][k];
int m=0,n=0,i,k=0,temp;
for(i=0;i<3;i++)
{
for (k = 0; k < 3; k++)
if (left.Draw[i][k] == 0)
{
m = i;
n = k;
flag=true;
break;
}
if(flag==true)
break;
}
if(n==0) //如果不可以往左边移动,则不变
return this;
else{
temp=left.Draw[m][n];
left.Draw[m][n]=left.Draw[m][n-1];
left.Draw[m][n-1]=temp;
return left;
}
}
public Node right() //生成空格向右移动的节点
{
boolean flag=false;
Node right=new Node();
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
right.Draw[i][k]=this.Draw[i][k];
int m=0,n=0,i,k=0,temp;
for(i=0;i<3;i++)
{
for (k = 0; k < 3; k++)
{
if (right.Draw[i][k] == 0)
{
m = i;
n = k;
flag=true;
break;
}
}
if(flag==true)
break;
}
if(n==2) //如果不可以往左边移动,则不变
return this;
else{
temp=right.Draw[m][n];
right.Draw[m][n]=right.Draw[m][n+1];
right.Draw[m][n+1]=temp;
return right;
}
}
public Node up() //生成空格向上移动的节点
{
boolean flag=false;
Node up=new Node();
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
up.Draw[i][k]=this.Draw[i][k];
int m=0,n=0,i,k=0,temp;
for(i=0;i<3;i++)
{
for (k = 0; k < 3; k++)
if (up.Draw[i][k] == 0)
{
m = i;
n = k;
flag=true;
break;
}
if(flag==true)
break;
}
if(m==0) //如果不可以往左边移动,则不变
return this;
else{
temp=up.Draw[m][n];
up.Draw[m][n]=up.Draw[m-1][n];
up.Draw[m-1][n]=temp;
return up;
}
}
public Node down() //生成空格向下移动的节点
{
boolean flag=false;
Node down=new Node();
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
down.Draw[i][k]=this.Draw[i][k];
int m=0,n=0,i,k=0,temp;
for(i=0;i<3;i++)
{
for (k = 0; k < 3; k++)
if (down.Draw[i][k] == 0)
{
m = i;
n = k;
flag=true;
break;
}
if(flag==true)
break;
}
if(m==2) //如果不可以往左边移动,则不变
return this;
else{
temp=down.Draw[m][n];
down.Draw[m][n]=down.Draw[m+1][n];
down.Draw[m+1][n]=temp;
return down;
}
}
public void print()
{
for(int i=0;i<3;i++)
{
for (int k = 0; k < 3; k++)
{
if (Draw[i][k] != 0)
System.out.print(Draw[i][k]);
else System.out.print(" ");
}
System.out.println();
}
}
public boolean eq(Node A)
{
for(int i=0;i<3;i++)
for(int k=0;k<3;k++)
if(this.Draw[i][k]!=A.Draw[i][k])
return false;
return true;
}
}
Method方法类实现
public class Method
{
boolean flag=false;
Node start=new Node();
Node target=new Node();
List<Node> openlist=new ArrayList<Node>();
List<Node> closelist=new ArrayList<Node>();
static int g=0;
Scanner in=new Scanner(System.in);
public void show()
{
Stack<Node> stack=new Stack<Node>();
Node now=target;
while(now.eq(start)==false)
{
stack.push(now);
now=now.father;
}
int amount=stack.size()+1;
System.out.println("初始状态为:");
start.print();
System.out.println("目标状态为:");
target.print();
System.out.println("**********************************************");
System.out.println("步数为"+(amount-1));
System.out.println("路径如下:");
while(stack.empty()==false)
{
stack.pop().print();
System.out.println("---------------------------");
}
}
public Method()
{
System.out.println("输入初始九宫格,空格用0代替");
start.Input();
System.out.println("输入目标九宫格,空格用0代替");
target.Input();
}
public boolean exist(Node A) //判断节点A的存在情况
{
for(int i=0;i<closelist.size();i++)
if(A.eq(closelist.get(i))==true)
return false;
for(int i=0;i<openlist.size();i++)
if(A.eq(openlist.get(i))==true)
return false;
return true;
}
public void A_Star()
{
long startTime=System.currentTimeMillis();
int g=0;
Node now=start;
Node nn=new Node();
openlist.add(start);
int min;
int count=0;
while(openlist.isEmpty()==false)
{
if(count>100000)
{
System.out.println("答案不存在");
flag=true;
break;
}
min=0;
for(Node b:openlist)
{
if((b.Function(target))<(openlist.get(min).Function(target))) //遍历openlist找到F值最低的节点
{
min = openlist.indexOf(b);
}
}
now=openlist.get(min); //将F值最低的节点设置为当前节点
closelist.add(openlist.get(min)); //将该节点移入closelist中
openlist.remove(min);
if(now.eq(now.left())==false&&exist(now.left())==true)
{
nn=now.left();
nn.father=now;
nn.deep=now.deep+1;
openlist.add(nn);
}
if(now.eq(now.right())==false&&exist(now.right())==true)
{
nn=now.right();
nn.father=now;
nn.deep=now.deep+1;
openlist.add(nn);
}
if(now.eq(now.up())==false&&exist(now.up())==true)
{
nn=now.up();
nn.father=now;
nn.deep=now.deep+1;
openlist.add(nn);
}
if(now.eq(now.down())==false&&exist(now.down())==true)
{
nn=now.down();
nn.father=now;
nn.deep=now.deep+1;
openlist.add(nn);
}
for(Node b:openlist)
if(b.eq(target)==true)
{
System.out.println("找到终点");
target.father=b.father;
flag=true;
long EndTime=System.currentTimeMillis();
System.out.println("A星算法执行时间为"+(EndTime-startTime)/1000.0+"s");
break;
}
if(flag==true)
break;
count++;
}
}
}
主函数
public static void main(String[] args)
{
Method a=new Method();
long startTime=System.currentTimeMillis();
a.A_Star();
if(a.flag==true)
a.show();
long endTime=System.currentTimeMillis();
System.out.println("总程序运行时间: "+(endTime-startTime)/1000.0+"s");
}