数据结构课程实践(2)-代码实现

数据结构课程实践(2)

一.题目:隐式图的搜索问题

----代码实现

1.结点类

public class Node {
    //存储当前状态的情况
    int [][]nowState=new int[3][3];
    Node parent=null;
    Node child1=null,child2=null,child3=null,child4=null;
    private int f;//价值
    int h=0;//层数
    public Node(int [][]a,Node p,Node c1,Node c2,Node c3,Node c4,int h){
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++)
                nowState[i][j]=a[i][j];
        }
        child1=c1;
        child2=c2;
        child3=c3;
        child4=c4;
        this.h=h;
    }
    public void setF(int g)
    {
        f=g+h;
    }
    public int getF(){
        return f;
    }
}

2.A*算法实现类

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Doit {
    Node start;
    Node target;
    List<Node> list=new ArrayList<>();
    List<Node> path=new ArrayList<>();
    Scanner scanner=new Scanner(System.in);
    public Doit(){
        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();
        start=new Node(origin,null,null,null,null,null,0);
        System.out.println("目标位置:");
        for(int i=0;i<3;i++)
            for (int j = 0; j < 3; j++)
                purpose[i][j]=scanner.nextInt();
        target=new Node(purpose,null,null,null,null,null,0);
    }
    //判断是否可行
    public boolean isExist(Node a1,Node a2){
        int []b1=new int[9];
        int []b2=new int[9];
        int pd1=0,pd2=0,n1=0,n2=0;
        int i,j;
        for(i=0;i<3;i++) {
            for(j=0;j<3;j++){
                b1[n1++]=a1.nowState[i][j];
                b2[n2++]=a2.nowState[i][j];
            }
        }
        for(i=0;i<9;i++){
            for(j=0;j<i;j++){
                if(b1[j]>b1[i]&&b1[j]!=0&&b1[i]!=0)
                    pd1++;
            }
        }
        for(i=0;i<9;i++){
            for(j=0;j<i;j++){
                if(b2[j]>b2[i]&&b2[j]!=0&&b2[i]!=0)
                    pd2++;
            }
        }
        if(pd1%2==pd2%2)
            return true;
        else
            return false;
    }
    public boolean isEqual(Node a1,Node a2){
        for(int i=0;i<3;i++) {
            for(int j=0;j<3;j++){
                if(a1.nowState[i][j]!=a2.nowState[i][j])
                    return false;
            }
        }
        return true;
    }
    public void show(){
        System.out.println("移动步骤如下:");
        for(int k=path.size()-1;k>=0;k--)
        {
            System.out.println(path.size()-k+":");
            for(int i=0;i<3;i++) {
                for(int j=0;j<3;j++){
                    System.out.print(path.get(k).nowState[i][j]+" ");
                }
                System.out.println();
            }
        }
    }
    public void add(Node leaf){
        int tmp;
        Node p;
        int [][]a=new int[3][3];
        int [][]b=new int[3][3];
        int [][]c=new int[3][3];
        int [][]d=new int[3][3];
        for(int i=0;i<3;i++) {
            for(int j=0;j<3;j++){
                a[i][j]=leaf.nowState[i][j];
                b[i][j]=leaf.nowState[i][j];
                c[i][j]=leaf.nowState[i][j];
                d[i][j]=leaf.nowState[i][j];
            }
        }
        int x=0,y=0;
        for(int i=0;i<3;i++) {
            for(int j=0;j<3;j++){
                if(a[i][j]==0)
                {
                    x=i;
                    y=j;
                }
            }
        }
        if ((x - 1) >= 0)
        {
            tmp=a[x][y];
            a[x][y]=a[x-1][y];
            a[x-1][y]=tmp;
            p = new Node(a,null,null,null,null,null,0);
            if (!compare(start, p))
            {
                leaf.child1=p;p.parent=leaf;
                p.h=leaf.h+1;
                int count=differentNum(p,target);
                p.setF(count);
                list.add(p);
            }
        }
        if (x + 1 <= 2)
        {
            tmp=b[x][y];
            b[x][y]=b[x+1][y];
            b[x+1][y]=tmp;
            p = new Node(b,null,null,null,null,null,0);
            if (!compare(start, p))
            {
                leaf.child2=p;p.parent=leaf;
                p.h=leaf.h+1;
                int count=differentNum(p,target);
                p.setF(count);
                list.add(p);
            }
        }
        if (y - 1 >= 0)
        {
            tmp=c[x][y];
            c[x][y]=c[x][y-1];
            c[x][y-1]=tmp;
            p = new Node(c,null,null,null,null,null,0);
            if (!compare(start, p))
            {
                leaf.child3=p;p.parent=leaf;
                p.h=leaf.h+1;
                int count=differentNum(p,target);
                p.setF(count);
                list.add(p);
            }
        }
        if (y + 1 <= 2)
        {
            tmp=d[x][y];
            d[x][y]=d[x][y+1];
            d[x][y+1]=tmp;
            p = new Node(d,null,null,null,null,null,0);
            if (!compare(start, p))
            {
                leaf.child4=p;p.parent=leaf;
                p.h=leaf.h+1;
                int count=differentNum(p,target);
                p.setF(count);
                list.add(p);
            }
        }
    }
    public boolean compare(Node root,Node p){
        if (root != null && isEqual(root,p))return true;
        if (root.child1 != null)compare(root.child1, p);
        if (root.child2 != null)compare(root.child2, p);
        if (root.child3 != null)compare(root.child3, p);
        if (root.child4 != null)compare(root.child4, p);
        return false;
    }
    public int differentNum(Node p,Node q){
        int count=0;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                if(p.nowState[i][j]!=q.nowState[i][j])
                    count++;
                return count;
    }
    public void aStar(){
        if (isExist(start,target)) {
            Node p=start;
            list.add(p);
            while(!isEqual(p,target)){
                list.remove(0);
                add(p);
                sort();
                p=list.get(0);
            }
            Node q = p;
            while (q != null)
            {
                path.add(q);
                q = q.parent;
            }
            show();
        }
        else{
            System.out.println("不可行!");
        }
    }
    public void sort(){
        Node node;
        int left=0,right=list.size()-1;
        while(left<right)
        {
            for(int i=left+1;i<=right;i++){
                if(list.get(left).getF()>list.get(i).getF()){
                    node=list.get(i);
                    list.set(i,list.get(left));
                    list.set(left,node);
                }
            }
            left++;
            for(int i=right-1;i>=left;i--){
                if(list.get(right).getF()<list.get(i).getF()){
                    node=list.get(i);
                    list.set(i,list.get(right));
                    list.set(right,node);
                }
            }
            right--;
        }
    }
}

3.主类

(仅用来执行)

public class Main {
    public static void main(String[]args){
        Doit doit=new Doit();
        doit.aStar();
    }
}

二.思路概括

首先通过构建结点类,存储上下左右四个方向的状态,并用parent结点记录其原来位置,通过A*算法的需要,构建评估价值的函数,即F(n)=g(n)+h(n)
其次构建隐式图的主要运作类
1.对是否可行的判断(奇偶性判断)放在一开始,若不可行,即不能到达目标位置,则直接,跳过。
2.构建判断两个二维数组是否相等的函数,作为结束的判断,以及中间查重的步骤。
3.构建g(n)函数,即两个二维数组有多少数字不相同。
4.构建主要的运行函数,通过对于四个方向的判断,增添其子节点。通过循环不断添加,直到达到目标位置。
5.输出函数,逆序输出,从到达的目标位置,不断寻找父结点存到一个新的列表里。
F(n)函数用于对列表再排序,找到价值最大的结点,寻找他的子节点。

三.运行结果

运行结果

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nightelves11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值