实验2隐式图的搜索代码

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();
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值