package Astar;
import java.util.*;
public class Astar {
private int N=3;
Scanner input=new Scanner(System.in);
int Map[][]=new int[N][N];
int target[][]=new int[N][N];
List<Node> openList=new ArrayList<>();
List<Node> closeList=new ArrayList<>();
HashMap<Integer,int []> targetmap=new HashMap<>();
List<Node> nodeList=new ArrayList<>();
Node Start;
Node Target;
Comparator<Node> comparator=new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
if(o1.getF()>o2.getF())
return 1;
else if(o1.getF()==o2.getF())
return 0;
else
return -1;
}
};
public Astar(){
if(init()) {
A_algorithm();
}else{
System.out.println("无解");
}
}
boolean init(){
System.out.println("请输入八数码的初始状态:");
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
Map[i][j]=input.nextInt();
}
}
Start=new Node();
Start.setState(Map);
System.out.println("请输入八数码的目标状态:");
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
target[i][j]=input.nextInt();
int index[]={i,j};
targetmap.put(target[i][j],index);
}
}
Target=new Node();
Target.setState(target);
if(isSolve(Target)){
return true;
}else{
return false;
}
}
public boolean isSolve(Node target){
int startNum[]=new int[N*N];
int endNum[] = new int[N*N];
int st = 0;
int et = 0;
for (int i = N * N - 2; i >= 0; i--) {
for (int j = i - 1; j >= 0; j--) {
if (startNum[i] > startNum[j])
st++;
if (endNum[i] > endNum[j])
et++;
}
}
if (st % 2 == et % 2)
return true;
return false;
}
int IndexInList(List<Node> list,Node node){
for (int index = 0; index < list.size(); index++) {
int i = 0,j=0;
for (i = 0; i <N; i++) {
for(j=0;j<N;j++) {
if ((list.get(index).getState()[i][j]) != node.getState()[i][j])
break;
}
if (j < N)
break;
}
if (i==N&&j==N) {
return index;
}
}
return -1;
}
public boolean isCanMove(int x,int y){
if(x<0||x>=3||y<0||y>=3){
return false;
}
return true;
}
Node getNext(Node now,int direction){
int dx[]=new int[]{0,0,-1,1};
int dy[]=new int[]{-1,1,0,0};
Node next=new Node();
int temp[][]=new int[N][N];
for(int i=0;i<N;i++){
for(int j=0;j<N;j++)
temp[i][j]=now.getState()[i][j];
}
int zeroIndex[]=now.getZeroIndex();
int x0=zeroIndex[0];
int y0=zeroIndex[1];
int nextZeroIndex=0;
int nextx,nexty;
nextx=x0+dx[direction];
nexty=y0+dy[direction];
if(isCanMove(nextx,nexty)){
temp[x0][y0]=now.getState()[nextx][nexty];
temp[nextx][nexty]=0;
List<Node> path=new ArrayList<>();
path.addAll(now.path);
next.setState(temp);
next.setPath(path);
return next;
}else{
return null;
}
}
void A_algorithm(){
Start.path.add(Start);
openList.add(Start);
nodeList.add(Start);
while(!openList.isEmpty()){
openList.sort(comparator);
Node best=openList.get(0);
openList.remove(0);
closeList.add(best);
if(best.isTarget(Target)){
System.out.println("-------打印路径------");
for(int i=0;i<best.path.size();i++){
System.out.println("第"+i+"次移动");
best.path.get(i).print();
}
System.out.println("共扩展了"+nodeList.size()+"个节点");
return;
}
for(int i=0;i<4;i++){
Node next=getNext(best,i);
if(next!=null){
if(IndexInList(closeList,next)==-1){
int index=IndexInList(openList,next);
if(index>=0){
if(next.getG()<openList.get(index).getG()){
openList.remove(index);
next.setParent(best);
next.setUp2(Target,targetmap);
next.path.add(next);
openList.add(next);
nodeList.add(next);
}
}else{
next.setParent(best);
next.setUp2(Target,targetmap);
next.path.add(next);
openList.add(next);
nodeList.add(next);
}
}
}
}
}
}
}
class Node {
private int N=3;
int state[][]=new int[3][3];
private int f;
private int g;
private int h;
private Node parent;
List<Node> path=new ArrayList<>();
public Node(){
}
public void setUp(Node target) {
int num=0;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
if(state[i][j]!=target.getState()[i][j]){
num++;
}
}
this.h = num;
if(this.parent==null){
this.g=0;
}else{
this.g=this.parent.getG()+1;
}
this.f=this.g+this.h;
}
public void setUp2(Node target,Map<Integer,int[]> map){
int num = 0;
for (int row = 0; row < N; row++) {
for (int cow = 0; cow < N; cow++) {
if (cow != 0 && state[row][cow] != target.getState()[row][cow]){
num += Math.abs(row - map.get(state[row][cow])[0]) + Math.abs(cow - map.get(state[row][cow])[1]);
}
}
}
this.h = num;
if(this.parent==null){
this.g=0;
}else{
this.g=this.parent.getG()+1;
}
this.f=this.g+this.h;
}
public int[][] getState() {
return state;
}
public void setState(int[][] state) {
this.state = state;
}
public int getF() {
return f;
}
public void setF(int f) {
this.f = f;
}
public int getG() {
return g;
}
public void setG(int g) {
this.g = g;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public List<Node> getPath() {
return path;
}
public void setPath(List<Node> path) {
this.path = path;
}
public boolean isTarget(Node target){
int i = 0,j=0;
for (i = 0; i <N; i++) {
for(j=0;j<N;j++) {
if (state[i][j]!= target.getState()[i][j])
return false;
}
}
return true;
}
public int[] getZeroIndex(){
int x0 = 0, y0 = 0;
for (x0 = 0; x0 < N; x0++) {
boolean flag = false;
for (y0 = 0; y0 < N; y0++) {
if (state[x0][y0] == 0) {
flag = true;
break;
}
}
if (flag)
break;
}
return new int[]{x0, y0};
}
public void print(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
System.out.print(state[i][j]+" ");
}
System.out.println();
}
}
}
package Astar;
public class test {
public static void main(String[] args) {
Astar astar=new Astar();
}
}