NODE
package bao;
public class Node {
private int[][]nowState;
private int f;//价值 这个价值 是总数
private int h;//层数 是open表 到目标的步数,还有几步
private Node parent; //这个是close表里本层的上一层
public Node(int [][]nowState ,int h,Node parent){
this.nowState=nowState;
this.h=h;
this.parent=parent; //
}
public int getF() {
return f;//
}
public void setF(int g) {
this.f=g+h;
}
public int[][] getNowState() {
return nowState;
}
public void setNowState(int[][] nowState) {
this.nowState = nowState;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public int getH() {
return h;
}
public void setH(int h) {
this.h = h;
}
}
Map
package bao;
import java.util.ArrayList;
import java.util.List;
public class Map {
private Node start;
private Node target;
private List open=new ArrayList<>();
private Listclose=new ArrayList<>();
int x,y;//存空格位置
public Map(int [][]start,int[][]target){
this.start=new Node(start,0,null);
this.target=new Node(target,0,null);//先对开始和目标结果进行赋值
}
public int diffNum(Node p,Node q){
int num=0;
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
if(p.getNowState()[i][j]!=q.getNowState()[i][j])
num++;
}//p,q两个节点,i和j代表行和列,这个p q两个节点是为了对比close表里和目标状态差多少步,和目标状态不同就再进行一次比对,即 f=g+h中的h
}
return num;
}
public boolean isEqual(Node p,Node q){
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
if(p.getNowState()[i][j]!=q.getNowState()[i][j])
return false;//这是判断是否与目标点相等
}
}
return true;
}
public void findBlank(Node p){
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
if(p.getNowState()[i][j]==0){
x=i;y=j;
}//对九宫格进行遍历,找到那个空格,另行对他定义变量
}
}
}
public boolean isExist(Node p){
for(int i=0;i<close.size();i++){
if(isEqual(p,close.get(i)))//对两个值执行深度比较来确定是否它们是相等的
return true;//
//判断是否存在
}
return false;
}
public void addState(Node p){
Node q;
int [][]a;
//对上移操作
a=new int[3][3];//赋值
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
a[i][j]=p.getNowState()[i][j];
}
}
findBlank(p);
if(x-1>=0){
int tmp=a[x][y];
a[x][y]=a[x-1][y];
a[x-1][y]=tmp;//进行移动,数字和空格进行进行交换
q=new Node(a,p.getH()+1,p);//将还没进行的步骤放进open表里
if(!isExist(q)){
q.setF(diffNum(q,target));
open.add(q);
}
}
//对下移操作
a=new int[3][3];
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
a[i][j]=p.getNowState()[i][j];//剩下的操作基本一致就是判断条件根据向不同的位置移动略有调整
}
}
findBlank(p);
if(x+1<=2){
int tmp=a[x][y];
a[x][y]=a[x+1][y];
a[x+1][y]=tmp;
q=new Node(a,p.getH()+1,p);
if(!isExist(q)){
q.setF(diffNum(q,target));
open.add(q);
}
}
//对左移操作
a=new int[3][3];
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
a[i][j]=p.getNowState()[i][j];
}
}
findBlank(p);
if(y-1>=0){
int tmp=a[x][y];
a[x][y]=a[x][y-1];
a[x][y-1]=tmp;
q=new Node(a,p.getH()+1,p);
if(!isExist(q)){
q.setF(diffNum(q,target));
open.add(q);
}
}
//对右移操作
a=new int[3][3];
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
a[i][j]=p.getNowState()[i][j];
}
}
findBlank(p);
if(y+1<=2){
int tmp=a[x][y];
a[x][y]=a[x][y+1];
a[x][y+1]=tmp;
q=new Node(a,p.getH()+1,p);
if(!isExist(q)){
q.setF(diffNum(q,target));
open.add(q);
}
}
}
public int sort() {
Node node = open.get(0);
int left = 0, right = open.size() - 1;
while (left < right) {
for (int i = left + 1; i <= right; i++) {
if (open.get(left).getF() > open.get(i).getF()) {
node = open.get(i);
open.set(i, open.get(left));
open.set(left, node);
}
}
left++;
for (int i = right - 1; i >= left; i--) {
if (open.get(right).getF() < open.get(i).getF()) {
node = open.get(i);
open.set(i, open.get(right));
open.set(right, node);
}
}
right--;//把所有的步骤存进列表
}
return right;//这一步是从最小的开始排序,但是我觉得可以注释掉,直接找最小的节点类,但是删掉之后又运行不了,来不及从头开始看了
}
public void aStar(){
open.add(start);
Node p=null;
while(open!=null){//已经将open表里未执行的步骤执行没有完
p=open.get(0);
if(isEqual(p,target))
break;
open.remove(0);
close.add(p);
addState(p);
sort();
}
if(isEqual(p,target)){
List<Node>answer=new ArrayList<>();
while(p.getParent()!=null){
answer.add(p);
p=p.getParent();
}
System.out.println("运行步骤:");
for(int i=answer.size()-1;i>=0;i--){
System.out.println(answer.size()-i+":");
show(answer.get(i));
}
}
}
public void show(Node p){
for(int i=0;i<p.getNowState().length;i++){
for(int j=0;j<p.getNowState()[i].length;j++){
System.out.print(p.getNowState()[i][j]+" ");
}
System.out.println();
}//显示结果并倒叙输出
}
}
Main包
package bao;
import java.util.Scanner;
public class Main {
public static void main(String[]args){
Scanner scanner=new Scanner(System.in);
System.out.println(“起始位置:”);
int [][]origin=new int[3][3];
int [][]purpose=new int[3][3];
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
origin[i][j]=scanner.nextInt();
System.out.println(“目标位置:”);
for(int i=0;i<3;i++)
for (int j = 0; j < 3; j++)
purpose[i][j]=scanner.nextInt();
Map map=new Map(origin,purpose);//调用
map.aStar();
}
}