JavaSwing编程实现A*搜索算法界面模拟解决传教士与野人问题

有N个传教士和N个野人来到河边渡河,河岸有一条船,每次至多可供k人乘渡。河两岸以及船上的野人数目总是不超过传教士的数目(否则不安全,传教士有可能被野人吃掉)。即求解传教士和野人从左岸全部摆渡到右岸的过程中,任何时刻满足M(传教士数)≥C(野人数)和M+C≤k的摆渡方案。针对以上问题,采用java编程语言设计实现界面程序集成A*算法解决运输方案。

获取源码

一、程序设计

本次Java实现A*搜索算法界面模拟解决传教士与野人问题程序主要内容涉及:

主要功能模块:参数设置、演示控制、动画模拟、A算法实现与集成等
主要包含技术:JavaSwing,Java2D,算法
主要包含算法及方法:A
搜索算法,动画模拟

系统采用前端采用JavaSwing实现,后台服务基于java编程语言实现算法,界面动画,运输方案过程计算,配合A*算法实现传教士与野人问题输送过程中的冲突问题,系统前后端数据交互,采用界面监听器调用传输实现。

获取源码

二、效果实现

初始界面

![其他][1]

动态模拟

![其他][2]

其他效果省略

三、A*算法设计

本次毕设系统在计算过程中,主要采用A*算法,针对运输过程需要考虑的传教士数据,野人数据等抽象成具体的实体类封装各自属性,实现运输冲突解决,生成运输方案等。

算法代码

public class AStar {
    // 系统容忍最大数值
    final int N = 65535;
    // 船上可容纳人数
    private int kofmc;
    // 野人和传教士人数
    public int nofmc;
    // 当前已经产生的结点序号
    private int number;
    // 存放状态节点
    private Status tree[] = new Status[N];
    // 存放路径
    public Display dp[] = new Display[N];
    // 找到最优解的标识
    public int found = 0;
    public int Start = 0;
    // 路径节点数
    public int num;
    private boolean large = false;
    public AStar(int nofmc, int kofmc) {
        this.nofmc = nofmc;
        this.kofmc = kofmc;
        if(this.nofmc >= N) {
            large = true;
            found = -1;
            System.out.println("输入太大!");
            return;
        }
        for(int i = 0; i < N; i++) {
            tree[i] = new Status();
            dp[i] = new Display();
        }
    }
    // 估计函数
    private float estimate(int M,int C,int B,int depth) {
        float retu = depth+B+((float)M+C)/kofmc;
        return retu;
    }
    //总的约束条件
    private boolean res(int M,int C) {
        return ((M==C)&&(M<=nofmc)&&(C<=nofmc)&&(M>=0)&&(C>=0))||((M==0)&&(C<=nofmc)&&(C>=0))||((M==nofmc)&&(C>=0)&&(C<=nofmc));
    }
    //判断是否为父结点
    private boolean isParent(int M, int C, int B, int depth, int target) {
        Status ps = null;
        ps=new Status();
        int point = target;
        ps.M = tree[point].M;
        ps.C = tree[point].C;
        ps.B = tree[point].B;
        ps.depth = tree[point].depth;
        ps.point = tree[point].point;
        while(ps.point != -1) {
            int ms,cs,bs;
            ms = ps.M;
            cs = ps.C;
            bs = ps.B;
            if((M==ms)&&(C==cs)&&(B!=bs)) {
                return true;
            }
            point = ps.point;
            ps.M = tree[point].M;
            ps.C = tree[point].C;
            ps.B = tree[point].B;
            ps.depth = tree[point].depth;
            ps.point = tree[point].point;
        }
        return false;
    }
    // 生成新节点
    private void create(int M,int C,int B,int depth,int target) {
        if(res(M,C)) {
            if(!(isParent(M,C,B,depth,target))) {
                // 在不在表中的标志
                int signal=0;
                for(int i = 0; i <= number; i++) {
                    int sign = tree[i].oorc;
                    int ms = tree[i].M;
                    int cs = tree[i].C;
                    int bs = tree[i].B;
                    int ds = tree[i].depth;
                    // 如果在open表中
                    if(sign == 0) {
                        if((M==ms)&&(C==cs)&&(B!=bs)) {
                            signal=1;
                            if(depth<(ds-1)) {
                                tree[i].point = target;
                                tree[i].depth = tree[target].depth+1;
                            }
                            break;
                        }
                    }
                    // 如果在closed表中
                    if(sign==1) {
                        if((M==ms)&&(C==cs)&&(B!=bs)) {
                            signal=1;
                            if(depth<(ds-1)) {
                                tree[i].point = target;
                                tree[i].depth = tree[target].depth+1;
                            }
                        }
                    }
                }
                //如果不在表中
                if(signal == 0) {
                    number++;
                    if(number >= N) {
                        found = -1;
                        System.out.println("数值太大!");
                        return;
                    }
                    tree[number].M=M;
                    tree[number].C=C;
                    tree[number].B=(B==0?1:0);
                    tree[number].depth=tree[target].depth+1;
                    tree[number].point = target;
                    tree[number].oorc = 0;
                }
            }
        }
    }
    //扩展节点
    private void extend(int M,int C,int B,int depth,int target) {
        if(B == 1) {
            for(int i = 1; i <= kofmc; i++) {
                M -= i;
                create(M,C,B,depth,target);
                M += i;
            }
            for(int j = 1; j <= kofmc; j++) {
                C -= j;
                create(M,C,B,depth,target);
                C += j;
            }
            for(int k = 1; k < kofmc; k++) {
                M -= k;
                for(int x = 1; x <= ((kofmc>2*k)?k:(kofmc-k)); x++) {
                    C -= x;
                    create(M,C,B,depth,target);
                    C += x;
                }
                M+=k;
            }
        } else {
            for(int i = 1; i <= kofmc; i++) {
                M += i;
                create(M,C,B,depth,target);
                M -= i;
            }
            for(int j = 1; j <= kofmc; j++) {
                C += j;
                create(M,C,B,depth,target);
                C -= j;
            }
            for(int k = 1; k < kofmc; k++) {
                M += k;
                for(int x=1; x<=((kofmc>2*k)?k:(kofmc-k)); x++) {
                    C += x;
                    create(M,C,B,depth,target);
                    C -= x;
                }
                M -= k;
            }
        }
    }
    private void change(int target) {
        tree[target].oorc=1;
    }
    private int excellent() {
        float min=32767;
        int target=-1;
        for(int i = 0; i <= number; i++) {
            int or=tree[i].oorc;
            if(or == 0) {
                int M, C, B, depth;
                float m;
                M = tree[i].M;
                C = tree[i].C;
                B = tree[i].B;
                depth = tree[i].depth;
                m = estimate(M, C, B, depth);
                if(m < min) {
                    min = m;
                    target = i;
                }
            }
        }
        return target;
    }
    public void start() {
        if(large) {
            found = -1;
            return;
        }
        Start=1;
        found=0;
        number=0;
        // 初始化tree
        tree[0].M=nofmc;
        tree[0].C=nofmc;
        tree[0].B=1;
        tree[0].depth=0;
        tree[0].oorc=0;
        tree[0].point = -1;
        int target=0;
        int point;
        point = target;
        while(point != -1) {
            int M,C,B,depth,mt,ct;
            M = tree[target].M;
            C = tree[target].C;
            B = tree[target].B;
            depth = tree[target].depth;
            extend(M,C,B,depth,target);
            change(target);
            target=excellent();
            if(target == -1) {
                System.out.println("no solution");
                break;
            }
            if(number >= N) {
                found = -1;
                System.out.println("too large number course exit!");
                break;
            }
            point = target;
            mt=tree[target].M;
            ct=tree[target].C;
            if((mt==0)&&(ct==0)) {
                int ps;
                ps = target;
                int numtemp=0;
                while(ps != -1) {
                    numtemp++;
                    ps = tree[ps].point;
                }
                num = numtemp;
                ps = target;
                while(ps != -1) {
                    numtemp--;
                    dp[numtemp].missi =tree[ps].M;
                    dp[numtemp].canni =tree[ps].C;
                    dp[numtemp].boat=tree[ps].B;
                    ps = tree[ps].point;
                }
                found=1;
                break;
            }
        }
    }
}

获取源码
联系方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值