迪杰斯特拉算法(最短路径和长度都给出)

迪杰斯特拉算法

算法思想:

路段权值非负(一般都能满足),通过遍历各路段的路阻(权值),获取起点到其他各个点的最短路径长度。N个点需迭代N-1次。注意事项看代码:

所使用的网络图如图:

在这里插入图片描述


import java.util.Arrays;
public class Test1 {
    public static void main(String[] args) {
        //这里为用户输入网络图的权值矩阵,本质就是各路段的路阻在此处进行表示
        int MAX=Integer.MAX_VALUE;//无法到达时使用这个int最大值表示
        int[][] weight={
                {0,1,12,MAX,MAX,MAX},
                {MAX,0,9,3,MAX,MAX},
                {MAX,MAX,0,MAX,5,MAX},
                {MAX,MAX,4,0,13,15},
                {MAX,MAX,MAX,MAX,0,4},
                {MAX,MAX,MAX,MAX,MAX,0}
        };//行号代表着起点,列号代表着终点
        //接下来就是选择出发点,并给出一个函数算出这个起点到其他各点的最短距离
        int start=0;//0可以作起点是因为,我们后续将0视作下标
        System.out.println(Arrays.deepToString(func(weight,start)));
    }
    private static int[][] func(int[][] weight,int start){
        //进行迪杰斯特拉算法
        boolean visit[]=new boolean[weight.length];//用以标记每个点是否被访问过
        int[] res=new int[weight.length];//用以记录起点到每一个点的最短距离
        int route[]=new int[weight.length];//用以记录最短路径的路线怎么走
        route[0]=start;//起点必定是start了
        int[][] answer=new int[2][weight.length];

        //初始化起点到每个点的距离
        for(int i=0;i<weight.length;i++){
            res[i]=weight[start][i];
        }

        //接下来就是在其他点中进行遍历,每次迭代确定一个点纳入最短路径
        for(int i=1;i<weight.length;i++){//从1开始只是表明迭代n-1次就可以得到最短路径了!
            int min=Integer.MAX_VALUE;
            int p=0;//这个随意,用以记录即将纳入最短路径的点的下标
            //下面是对未标记点到出发点(不一定就是起点)的最短距离,找到了这个点后,将其设为true(已标记)
            for(int j=0;j<weight.length;j++){
                if(j!=start&&!visit[j]&&res[j]<min){//因为起点自始至终都没有设为true(中间的逻辑判断不包含第一个逻辑),所以要设一条点不能为起点
                    p=j;
                    min=res[j];//这个的含义是什么?意思就是找最小啊!没这个就不对!
                }
            }
            visit[p]=true;
            route[i]=p;//新纳入的点将记录至当前路线数组中

            //基于上述刚纳入最短路径的点,去以这个点为出发点作路径长度更新(因为最短路径此时就是必经过p点)
            for(int j=0;j<weight.length;j++){
                if(j==p||weight[p][j]==Integer.MAX_VALUE){
                    continue;
                }
                if(res[p]+weight[p][j]<res[j]){
                    res[j]=res[p]+weight[p][j];
                }
            }
        }
        answer[0]=route;//结果数组第一行给出最短路径的路线
        answer[1]=res;//结果数组的第二行给出起点到各个点的最短路径长度

        return answer;
    }
}

给出的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuoUWXMo-1642059692731)(C:\Users\LebronHarden\AppData\Roaming\Typora\typora-user-images\image-20220113153806497.png)]

含义为:路线:0->1->3->2->4->5为0-5的最短路径走法,如果指定的OD对不一样,可以调整weight数组使两者处于数组首尾行列即可。answer数组的第二个元素给出的是起点到各个点的最短距离!最后一个元素就是OD对之间的最短路径长度了!

总结🏝

  1. 上述代码的目的是:找出一个网络图中指定起点到其余各个点的最短距离。route已给出最短路径对应的路线(注意是从0下标开始走)。

  2. 代码主要功能体现在func()函数:对其进行实现的话,可概括为以下几个步骤:

    a.定义标记数组距离记录数组,并对其进行初始化

    b.迭代N-1次遍历完除起点外的所有其他的点

    c.针对上述每一次的遍历要做两件事:

    ​ ①:点更新:通过是否邻接和路径长短进行遍历获得。

    ​ ②:路径更新:上述每次点更新都会新纳入一个点进入最短路径,此步骤就是基于上述新纳入的点,去更新。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值