java數據結構最經濟的地下通道建設方案prim算法

MX是世界上第一大傳媒娛樂企業,該公司數十年的經營歷史中創作了很多經典影片,此外還經營着很多的規模十分宏大世界級的主題娛樂公園。最近MX公司剛和CX城市達成協定,共同投資建設C國國內唯一一家主題娛樂公園。

主題公園的經營管理部門計劃佈設m個固定的快餐飲品供應點爲遊客服務。希望遊客遊園時,絕對不要受到快餐店補貨車工作運行的影響,最好的辦法就是絕對不讓遊客在園中看到補貨車,絕對不讓遊客聽到補貨車的聲音。讓遊客覺得在園中任何一個餐飲點隨時都能買到食品和飲品,能得到無窮無盡的食品和飲品。因此設計團隊想把給m個餐飲點供貨的通道設置在地下,並在通道內部敷設一定的隔音材料,可是修造地下供貨通道的經濟代價與通道總長度成正比(每100米修造代價是M萬元),花費將是非常巨大的,不過遊客至上。

現在設計團隊手中已經有了m個餐飲點的座標位置(xy)信息,你是設計團隊的一員,團隊交給你的工作就是規劃一個地下通道建設方案,將m個餐飲點都連接起來且總修造代價儘可能地小。

 

 

隨機生成m個座標信息驗證你的算法和程序,如果最終程序求解的通道規劃方案不唯一,則輸出其中的任一方案即可(要求m>=30)。

 

解題代碼如下,註釋的較爲清楚,不在過多闡述。


import java.util.Random;

public class MyPrim {

    public static void main(String[] args) {
        Random random = new Random();
        //隨機生成m個座標信息
        int m = random.nextInt(30) + 30;
//        int m = 5;
        System.out.println("current size = " + m);
        //每個店鋪與其他店鋪的距離
        int[][] map = new int[m][m];
        for (int i = 0; i < m; i++) {
            //當前店鋪與之後的所有店鋪距離
            for (int j = i; j < m; j++) {
                if (i == j) {
                    map[i][j] = 0;
                } else {
                    //每個餐飲店最少隔100米
                    map[i][j] = random.nextInt(400) + 100;
                }
            }
            //把之前的店鋪距離賦值給當前店鋪
            for (int j = 0; j < i; j++) {
                map[i][j] = map[j][i];
            }
        }
        System.out.println(toString(map));
        //輸出最短距離
        System.out.println(startPrim(map, m));
    }

    private static int startPrim(int[][] map, int m) {
        //總距離
        int sumDistance = 0;
        //已經選擇過的餐飲店
        int[] selectedMap = new int[m];
        //默認都沒訪問過標記爲-1
        for (int i = 0; i < m; i++) {
            selectedMap[i] = -1;
        }
        //起點默認爲第一個,訪問標記爲0
        selectedMap[0] = 0;

        //記錄求解的通道規劃方案
        int startM = 0;
        int endM = 0;

        //遍歷除了第一個之後的每個店鋪
        for (int i = 0; i < m - 1; i++) {
            //當前店鋪的最近距離
            int minDistance = Integer.MAX_VALUE;
            int minMIndex = -1;
            //遍歷已經選擇過得餐飲店
            for (int j = 0; j < m; j++) {
                if (selectedMap[j] == 0) {
                    //開始尋找與該店最近的店
                    int[] currentM = new int[m];
                    //得到該店與其他未被選擇的店的距離
                    for (int k = 0; k < m; k++) {
                        if (selectedMap[k] != 0) {
                            //把二維數組裏第j行的數據賦值給當前店鋪
                            currentM[k] = map[j][k];
                        } else {
                            currentM[k] = 0;
                        }
                    }
                    //尋找最小值
                    for (int k = 0; k < m; k++) {
                        //如果距離不爲0,且最小距離大於當前距離
                        if (currentM[k] != 0 && minDistance > currentM[k]) {
                            //設置最小距離爲當前距離
                            minDistance = currentM[k];
                            //記錄店鋪下標
                            minMIndex = k;
                            //記錄方案
                            startM = j;
                            endM = k;
                        }
                    }
                    //當前這個選擇過的餐飲店鋪的最近距離店鋪找出來後,繼續循環找下一個的,直到循環完畢後找到最小的那個店鋪
                }
            }
            //設置minMIndex爲已選擇餐飲店
            selectedMap[minMIndex] = 0;
            //總距離計算
            sumDistance += minDistance;
            //輸出方案
            System.out.println("m" + startM + " is connected to m" + endM+", min distance is "+minDistance+", position["+startM+", "+endM+"]");
        }
        return sumDistance;
    }

    //輸出所有店鋪的距離信息
    static String toString(int[][] map) {
        StringBuilder s = new StringBuilder();
        for (int[] ints : map) {
            for (int j = 0; j < ints.length; j++) {
                if ((j + 1) == ints.length)
                    s.append(ints[j]).append("\n");
                else
                    s.append(ints[j]).append(" ");
            }
        }
        return s.toString();
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章