最短路径dijkstra和floyed

版权声明:本文为博主原创文章,未经博主允许不得转载。博客地址:http://www.fanlegefan.com/ https://blog.csdn.net/woloqun/article/details/80875734

闲来没事撸个最短路径代码,关于这两个算法可以参考下面两篇文章,写的太好了,我就用java再写一遍
dijkstra:https://www.cnblogs.com/he-px/p/6677063.html
floyed:https://blog.csdn.net/jeffleo/article/details/53349825

贴个用到的图,这个图也是从别人博客上抄过来的,(⊙o⊙)…
这里写图片描述

定义图

    static int[][] graph = new int[7][7];
    static int INF = 1000;
    static{
        graph[0][1] = 12;graph[1][0] = 12;
        graph[0][5] = 16;graph[5][0] = 16;
        graph[0][6] = 14;graph[6][0] = 14;
        graph[1][5] = 7;graph[5][1] = 7;
        graph[1][2] = 10;graph[2][1] = 10;
        graph[6][5] = 9;graph[5][6] = 9;
        graph[6][4] = 8;graph[4][6] = 8;
        graph[5][2] = 6;graph[2][5] = 6;
        graph[5][4] = 2;graph[4][5] = 2;
        graph[2][4] = 5;graph[4][2] = 5;
        graph[2][3] = 3;graph[3][2] = 3;
        graph[4][3] = 4;graph[3][4] = 4;

    }

dijkstra

 /**
     * 单源最短路径
     * @param start
     */
    public static void dijkstra(int start){
//        System.out.print(start+"-->");
        int[] costs = new int[graph.length];
        //记录start节点到各个节点的距离,初始化为最大距离
        for(int i=0;i<costs.length;i++) costs[i] = INF;
        costs[start] = 0;
        Queue<Integer> queue = new LinkedBlockingQueue<Integer>();
        //记录路径
        int[] path = new int[graph.length];

//        初始化队列,将与start节点相关联的节点添加到队列中,并且修改costs
        for(int i=0;i<costs.length;i++){
            if(graph[start][i]>0) {
                queue.offer(i);
                costs[i] = graph[start][i];
                path[i] = start;
            }
        }

        while(!queue.isEmpty()){
            //从队列中获取一个元素,然后获得该节点所有的邻接点,并修改cost
            Integer p = queue.poll();
//            System.out.print(p+"-->");
            for(int i=0;i<graph.length;i++){
                if(graph[p][i]>0){
                    if(costs[p]+graph[p][i]<costs[i]){
                        costs[i] = costs[p]+graph[p][i];
                        queue.offer(i);
                        path[i] = p;
                    }
                }
            }
        }

        System.out.println("start("+start+")节点到各节点之间的距离:");
        for(Integer i:costs){
            System.out.print(i+" ");
        }
        System.out.println();
        System.out.println("路径:");
        for(Integer i:path){
            System.out.print(i+" ");
        }
    }

输出如下

start(1)节点到各节点之间的距离:
12 0 10 13 9 7 16 
路径:
1 0 1 2 5 1 5 

floyed

/**
     * 弗洛伊德算法可以算出所有节点之间的最短距离,时间复杂度是(O(n3))
     */
    public static void floyed(){
        //存储中间节点
        int[][] D = new int[graph.length][graph.length];
        int[][] p = new int[graph.length][graph.length];
        for(int i=0;i<graph.length;i++){
            for(int j=0;j<graph.length;j++){
                p[i][j] = j;
                if(graph[i][j]>0){
                    D[i][j] = graph[i][j];
                }else{
                    if(i==j){
                        D[i][j]=0;
                    }else{
                        D[i][j] = INF;
                    }
                }
            }
        }

        for(int i=0;i<graph.length;i++){
            //遍历每一个中间点
            for(int j=0;j<graph.length;j++){
                for(int k=0;k<graph.length;k++){
                    if(j!=k){
                        if(D[j][k]>D[i][j]+D[i][k]){
                            D[j][k] = D[i][j]+D[i][k];
                            p[j][k] = p[j][i];
                        }
                    }
                }
            }
        }

        System.out.println("节点之间的距离:");
        for(int i=0;i<graph.length;i++){
            for(int j=0;j<graph.length;j++){
                System.out.print(D[i][j]+" ");
            }
            System.out.println();
        }

        System.out.println("打印所有路径:");
        for(int i=0;i<graph.length;i++){
            for(int j=0;j<graph.length;j++){
                if(i!=j) printPath(i,j,p,D);
            }
        }

    }

    public static void printPath(int v,int w,int[][] p,int[][] D){
        //求 v 到 w的最小路径
        System.out.printf("\n%d -> %d 的最小路径为:%d\n", v, w, D[v][w]);
        int k = p[v][w];
        System.out.printf("path: %d", v);//打印起点
        while(k != w){
            System.out.printf("-> %d", k);//打印中间点
            k = p[k][w];
        }
        System.out.printf("-> %d\n", w);
    }

输出如下

节点之间的距离:
0 12 22 22 18 16 14 
12 0 10 13 9 7 16 
22 10 0 3 5 6 13 
22 13 3 0 4 6 12 
18 9 5 4 0 2 8 
16 7 6 6 2 0 9 
14 16 13 12 8 9 0 
打印所有路径:

0 -> 1 的最小路径为:12
path: 0-> 1

0 -> 2 的最小路径为:22
path: 0-> 1-> 2

0 -> 3 的最小路径为:22
path: 0-> 5-> 4-> 3

0 -> 4 的最小路径为:18
path: 0-> 5-> 4

0 -> 5 的最小路径为:16
path: 0-> 5

0 -> 6 的最小路径为:14
path: 0-> 6

1 -> 0 的最小路径为:12
path: 1-> 0

1 -> 2 的最小路径为:10
path: 1-> 2

1 -> 3 的最小路径为:13
path: 1-> 2-> 3

1 -> 4 的最小路径为:9
path: 1-> 5-> 4

1 -> 5 的最小路径为:7
path: 1-> 5

1 -> 6 的最小路径为:16
path: 1-> 5-> 6

2 -> 0 的最小路径为:22
path: 2-> 1-> 0

2 -> 1 的最小路径为:10
path: 2-> 1

2 -> 3 的最小路径为:3
path: 2-> 3

2 -> 4 的最小路径为:5
path: 2-> 4

2 -> 5 的最小路径为:6
path: 2-> 5

2 -> 6 的最小路径为:13
path: 2-> 4-> 6

3 -> 0 的最小路径为:22
path: 3-> 4-> 5-> 0

3 -> 1 的最小路径为:13
path: 3-> 2-> 1

3 -> 2 的最小路径为:3
path: 3-> 2

3 -> 4 的最小路径为:4
path: 3-> 4

3 -> 5 的最小路径为:6
path: 3-> 4-> 5

3 -> 6 的最小路径为:12
path: 3-> 4-> 6

4 -> 0 的最小路径为:18
path: 4-> 5-> 0

4 -> 1 的最小路径为:9
path: 4-> 5-> 1

4 -> 2 的最小路径为:5
path: 4-> 2

4 -> 3 的最小路径为:4
path: 4-> 3

4 -> 5 的最小路径为:2
path: 4-> 5

4 -> 6 的最小路径为:8
path: 4-> 6

5 -> 0 的最小路径为:16
path: 5-> 0

5 -> 1 的最小路径为:7
path: 5-> 1

5 -> 2 的最小路径为:6
path: 5-> 2

5 -> 3 的最小路径为:6
path: 5-> 4-> 3

5 -> 4 的最小路径为:2
path: 5-> 4

5 -> 6 的最小路径为:9
path: 5-> 6

6 -> 0 的最小路径为:14
path: 6-> 0

6 -> 1 的最小路径为:16
path: 6-> 5-> 1

6 -> 2 的最小路径为:13
path: 6-> 4-> 2

6 -> 3 的最小路径为:12
path: 6-> 4-> 3

6 -> 4 的最小路径为:8
path: 6-> 4

6 -> 5 的最小路径为:9
path: 6-> 5

猜你喜欢

转载自blog.csdn.net/woloqun/article/details/80875734