博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最短路径之迪杰斯特拉算法

Posted on 2020-08-21 11:06  池塘鱼  阅读(73)  评论(0)    收藏  举报

https://www.jianshu.com/p/ff6db00ad866

这篇文章相当清楚。

对代码做了一点小改动,让输出结点名而不是结点下标。

package com.ex.greedy;

public class Dijkstra {

    static final int N=10000;

    public static void main(String[] args) {
        int[][] weight1={
                {0,4,N,2,N},
                {4,0,4,1,N},
                {N,4,0,1,3},
                {2,1,1,0,7},
                {N,N,3,7,0}
        };
        char[] nodes1={'A','B','C','D','E'};
        int start=0;
        int[] shortDis = dijkstra(weight1, nodes1, start);
        for (int i = 0; i < shortDis.length; i++) {
            System.out.println("从"+nodes1[start]+"出发到"+nodes1[i]+"的最短路径为:"+shortDis[i]);
        }
    }

    /**
     * 求起始顶点到各个顶点的最短路径,并输出最短路径经历的顶点
     * @param weight 邻接矩阵
     * @param nodes 顶点数组
     * @param start 起始顶点的下标
     * @return 返回起始顶点到各个顶点的最短路径距离
     */
    public static int[] dijkstra(int[][] weight, char[] nodes, int start) {
        //1.准备
        int n=nodes.length;//顶点个数
        int[] shortDis=new int[n];//记录S集合中从start到其余顶点的最短路径距离
        int[] visited=new int[n];//记录这个顶点的最短路径有没有求出来,1是已求出
        String path[]=new String[n];//记录start到其他各点最短路径的字符串表示
        for (int i = 0; i < n; i++) {
            path[i]=nodes[start]+"—>"+nodes[i];
        }
        //2.初始化
        visited[start]=1;
//        shortDis[start]=0;

        //3.循环
        for (int k = 1; k < n; k++) {//要加入除起始结点外的剩下n-1个顶点
            //3.1选择新结点
            int min=N,index=-1;
            for (int i = 0; i < n; i++) {
                if (visited[i]==0 && weight[start][i]<min){//选出一个距离初始顶点start最近的未标记顶点
                    min=weight[start][i];
                    index=i;
                }
            }
            //3.2将新结点加入集合
            visited[index]=1;
            shortDis[index]=min;
            //3.3更新
            for (int i = 0; i < n; i++) {
                //对集合U中的数据进行更新:如果‘start到中间结点index的距离’+‘index到当前顶点的距离’<‘目前start到当前顶点的最短距离’,就更新
                if (visited[i]==0 && weight[start][index]+weight[index][i]<weight[start][i]){
                    weight[start][i]=weight[start][index]+weight[index][i];
                    path[i]=path[index]+"—>"+nodes[i];
                }
            }
        }
        //输出路径
        for (int i = 0; i < n; i++) {
            System.out.println("从"+nodes[start]+"出发到"+nodes[i]+"的最短路径为:"+path[i]);
        }
        System.out.println("==================");
        //返回结果
        return shortDis;

    }

}

每次选择新顶点后,将新顶点加入集合S:置访问标记为1,将最短路径赋值到shortDis。

 

U集合中记录的最短距离实际是邻接矩阵中起始顶点那一行的数据。

每次选择新顶点后,对集合U中的数据进行更新:更新邻接矩阵中的最短路径距离和最短路径字符串。