Java實(shí)現(xiàn)A*搜索算法界面模擬解決傳教士與野人問(wèn)題稼跳,JavaSwing盟庞,A*算法

有N個(gè)傳教士和N個(gè)野人來(lái)到河邊渡河,河岸有一條船汤善,每次至多可供k人乘渡什猖。河兩岸以及船上的野人數(shù)目總是不超過(guò)傳教士的數(shù)目(否則不安全,傳教士有可能被野人吃掉)红淡。即求解傳教士和野人從左岸全部擺渡到右岸的過(guò)程中不狮,任何時(shí)刻滿足M(傳教士數(shù))≥C(野人數(shù))和M+C≤k的擺渡方案。針對(duì)以上問(wèn)題在旱,采用java編程語(yǔ)言設(shè)計(jì)實(shí)現(xiàn)界面程序集成A*算法解決運(yùn)輸方案摇零。

一、程序設(shè)計(jì)

本次Java實(shí)現(xiàn)A*搜索算法界面模擬解決傳教士與野人問(wèn)題程序主要內(nèi)容涉及:

主要功能模塊:參數(shù)設(shè)置桶蝎、演示控制驻仅、動(dòng)畫(huà)模擬谅畅、A算法實(shí)現(xiàn)與集成等
主要包含技術(shù):JavaSwing,Java2D噪服,算法
主要包含算法及方法:A
搜索算法毡泻,動(dòng)畫(huà)模擬

系統(tǒng)采用前端采用JavaSwing實(shí)現(xiàn),后臺(tái)服務(wù)基于java編程語(yǔ)言實(shí)現(xiàn)算法粘优,界面動(dòng)畫(huà)仇味,運(yùn)輸方案過(guò)程計(jì)算,配合A*算法實(shí)現(xiàn)傳教士與野人問(wèn)題輸送過(guò)程中的沖突問(wèn)題雹顺,系統(tǒng)前后端數(shù)據(jù)交互丹墨,采用界面監(jiān)聽(tīng)器調(diào)用傳輸實(shí)現(xiàn)。

二嬉愧、效果實(shí)現(xiàn)

初始界面

image.png

動(dòng)態(tài)模擬

gcys.gif

其他效果省略

三贩挣、A*算法設(shè)計(jì)

本次畢設(shè)系統(tǒng)在計(jì)算過(guò)程中,主要采用A*算法英染,針對(duì)運(yùn)輸過(guò)程需要考慮的傳教士數(shù)據(jù)揽惹,野人數(shù)據(jù)等抽象成具體的實(shí)體類(lèi)封裝各自屬性,實(shí)現(xiàn)運(yùn)輸沖突解決,生成運(yùn)輸方案等。

算法代碼

public class AStar {
    // 系統(tǒng)容忍最大數(shù)值
    final int N = 65535;
    // 船上可容納人數(shù)
    private int kofmc;
    // 野人和傳教士人數(shù)
    public int nofmc;
    // 當(dāng)前已經(jīng)產(chǎn)生的結(jié)點(diǎn)序號(hào)
    private int number;
    // 存放狀態(tài)節(jié)點(diǎn)
    private Status tree[] = new Status[N];
    // 存放路徑
    public Display dp[] = new Display[N];
    // 找到最優(yōu)解的標(biāo)識(shí)
    public int found = 0;
    public int Start = 0;
    // 路徑節(jié)點(diǎn)數(shù)
    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();
        }
    }
    // 估計(jì)函數(shù)
    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));
    }
    //判斷是否為父結(jié)點(diǎn)
    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;
    }
    // 生成新節(jié)點(diǎn)
    private void create(int M,int C,int B,int depth,int target) {
        if(res(M,C)) {
            if(!(isParent(M,C,B,depth,target))) {
                // 在不在表中的標(biāo)志
                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("數(shù)值太大!");
                        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;
                }
            }
        }
    }
    //擴(kuò)展節(jié)點(diǎn)
    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;
            }
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疯溺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哎垦,更是在濱河造成了極大的恐慌囱嫩,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漏设,死亡現(xiàn)場(chǎng)離奇詭異墨闲,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)郑口,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)鸳碧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人犬性,你說(shuō)我怎么就攤上這事瞻离。” “怎么了乒裆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵套利,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)肉迫,這世上最難降的妖魔是什么验辞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮昂拂,結(jié)果婚禮上受神,老公的妹妹穿的比我還像新娘。我一直安慰自己格侯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布财著。 她就那樣靜靜地躺著联四,像睡著了一般。 火紅的嫁衣襯著肌膚如雪撑教。 梳的紋絲不亂的頭發(fā)上朝墩,一...
    開(kāi)封第一講書(shū)人閱讀 51,727評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音伟姐,去河邊找鬼收苏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛愤兵,可吹牛的內(nèi)容都是我干的鹿霸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼秆乳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼懦鼠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起屹堰,我...
    開(kāi)封第一講書(shū)人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肛冶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后扯键,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體睦袖,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年荣刑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了馅笙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘶摊,死狀恐怖延蟹,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叶堆,我是刑警寧澤阱飘,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響沥匈,放射性物質(zhì)發(fā)生泄漏蔗喂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一高帖、第九天 我趴在偏房一處隱蔽的房頂上張望缰儿。 院中可真熱鬧,春花似錦散址、人聲如沸乖阵。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞪浸。三九已至,卻和暖如春吏祸,著一層夾襖步出監(jiān)牢的瞬間对蒲,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工贡翘, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹈矮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓鸣驱,卻偏偏與公主長(zhǎng)得像泛鸟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丐巫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容