Dijkstra原理及java实现

一、Dijkstra原理简介

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。

其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。

有向图和无向图均可求解。话不多说,直接图解。

(A1)示例1:求A到F的最短路径过程详解

Dijkstra无向图

//距离矩阵如下
int M=2000;
int[][] weight={
        {0,6,3,M,M,M},
        {6,0,2,5,M,M},
        {3,2,0,3,4,M},
        {M,5,3,0,2,3},
        {M,M,4,2,0,5},
        {M,M,M,3,5,0}
};
先看如下表格解释(A出发到F):

这里写图片描述

以上表格如果没有完全明白,没关系。以下给出每一步的过程图(A出发到F)。

step1:(初始化)

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
063MMM
visited=1 lastNode

step2:

初始化为以上状态。接下来只需要两步就能完成:
(I)在i未访问中,末节点的shortPath值+该节点到其他未访问节点i的值的和 与 节点i的shortPath比较,如前者小,则shortPath[i]更新成这个小的。
同时更新路线path。(第一次shortPath[0]=0,不变)

(II)在i未访问中,找到shortPath数组中最小的。将其标记为以访问状态visited=1,即C shortPath[2],将该节点记为末节点.

标色表示未访问的节点,可能被更新。

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
063MMM
visited=1visited=1 lastNode

step3:

重复step2的过程。

(I)shortPath[2]+weight[2][i](i=1,3,4,5)<shortPath[i] ? 更新shortPath[i] : 不更新

(II)未访问节点B D E F 即索引[1][3][4][5]。最小B。visited[1]=1.
ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
05(3+2<6)36(3+3)7(3+4)M
visited=1visited=1
visited=1 lastNode
过程如下:

这里写图片描述

step4:

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
053 shortPath[[1]]+weight[[1]][[3]]>6( 还是6)shortPath[[1]]+weight[[1]][[4]] 还是7shortPath[[1]]+weight[[1]][[5]] 还是M
visited=1visited=1visited=1
visited=1 lastNode

step5:

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
0536shortPath[[3]]+weight[[3]][[4]] 还是7shortPath[[3]]+weight[[3]][[5]]=9 更新为9
visited=1visited=1visited=1visited=1
visited=1 lastNode

step6:

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
05367shortPath[[4]]+weight[[4]][[5]]=7+5>9 还是为9
visited=1visited=1visited=1visited=1visited=1
visited=1 lastNode

最终

ABCDEF
shorPath[0]shorPath[[1]]shorPath[[2]]shorPath[[3]]shorPath[[4]]shorPath[[5]]
053679
visited=1visited=1visited=1visited=1visited=1visited=1 lastNode

可知:A–>F最小值:9

(A2)示例1:求A到F的最短路径的java代码

import java.util.Scanner;

/*
 * @author WangHongbing 284734261@qq.com *
 */
public class Dijkstra { 
    /**
     * 
     * @param weight n*n维数组。第i行(i=0,1,...n-1)表示节点i到其他节点的权值
     * @param start  起始节点,索引
     * @return       n维数组,到其他节点的最短路径
     */
    public static int[] dijkstra(int[][] weight,int start){
        int vertexNum = weight.length;            //顶点个数
        int[] shortPath=new int[vertexNum];       //保存最短路径值

        String[] path = new String[vertexNum];    //具体路径存在字符串中

        int[] visited = new int[vertexNum];       //顶点i是否已经求过

        //初始化
        shortPath[start]=0;
        visited[start]=1;       

        int M=2000;                               //将2000当成无穷大
        //初始化shortPath数组
        shortPath[start]=0;
        path[start]=start+"";
        for(int i=0;i<shortPath.length;i++){
            if(i!=start){
                shortPath[i]=M;     
            }
        }

        int lastNode=start;

        for(int count=1;count<vertexNum;count++){
            //第一次,weight[0][1],weight[0][2],weight[0][3],..weight[0][5]中取最小的
            int dmin = Integer.MAX_VALUE;
            int k=0;
            for(int i=0;i<vertexNum;i++){

                if(visited[i]==0 && shortPath[lastNode]+weight[lastNode][i]<shortPath[i]){
                    //拿lastNode到i的值+之前shortPath中lastNode的值 和 对应shortPath比较。小则更新路线
                    //然后再找到一个最小的作为最后的节点
                    shortPath[i]=shortPath[lastNode]+weight[lastNode][i];
                    //路线更新存在path数组中                                     
                    path[i]=path[lastNode]+"-->"+i;                 
                }
                if(visited[i]==0 && shortPath[i]<dmin){
                    dmin=shortPath[i];
                    k=i;                        
                }
            }       
            lastNode=k;
            visited[k]=1;           
        }
        System.out.println(path[path.length-1]);
        return shortPath;
    }
    public static void main(String[] args) {

        int M=2000;
        int[][] weight={
                {0,10,M,30,100}, 
                {M,0,50,M,M}, 
                {M,M,0,M,10}, 
                {M,M,20,0,60}, 
                {M,M,M,M,0} 
        };
        int[][] weight2={
                {0,6,3,M,M,M},
                {6,0,2,5,M,M},
                {3,2,0,3,4,M},
                {M,5,3,0,2,3},
                {M,M,4,2,0,5},
                {M,M,M,3,5,0}
        };
        int[] shortPath  = dijkstra(weight2, 0);
        System.out.println(shortPath[shortPath.length-1]);      
    }
}


----------
//weight2输出

0-->2-->3-->5
9

二、华为2017春招题

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值