Dijkstra算法求解单源点到其余各顶点的最短距离

来源:互联网 发布:软件项目质量保证方案 编辑:程序博客网 时间:2024/05/29 07:17
单源点最短路径:

        给定带权有向图G和源点v, 求从v到G中其余各顶点的最短路径。

Dijkstra算法:

        Dijkstra提出了一个按路径“长度”递增的次序,逐步得到由给定源点到图的其余各点间的最短路径的算法:
        假设我们以邻接矩阵cost(代码中为A[ ]数组),表示所研究的有向网的代价矩阵。
        迪杰斯特拉算法需要一个顶点集合,初始时集合内只有一个源点V0 ,以后陆续将已求得最短路径的顶点加入到集合中,到全部顶点都进入集合了,过程就结束了。集合 可用一维数组来表示,设此数组为S(代码中为mark[ ]数组),凡在集合S以外的顶点,其相应的数组元素S[i]  为 -1 ,否则为 1 。

        另需一个一维数组D(代码中为dis[ ]数组),每个顶点对应数组的一个单元,记录从源点到其他各顶点当前的最短路径长度,其初值为D[i]=cost[V0][i],i=1…n。数组D中的数据随着算法的逐步进行要不断地修改
        定义了S集合和D数组并对其初始化后,迪杰斯特拉算法在进行中,都是从S之外的顶点集合中选出一个顶点w,使D[w]的值最小。于是从源点到达w只通过S中的顶点,把 w 加入集合S中,并调整D中记录的从源点到集合中每个顶点v的距离: 取D[v]和D[w]+cost[w][v]中值较小的作为新的D[v]
        重复上述,直到S中包含V中其余各顶点的最短路径。

实例:

                  

代码及解析:

package utils;import java.io.File;public class ShortestPath {static int INF = Global.INF;public static void dijkstraShortestPath(int v,int[][] A){int n = A[0].length;int[] dis = new int[n];int[] path = new int[n];int[] mark = new int[n];for(int i=0;i<n;i++){dis[i] = A[v][i];path[i] = v;mark[i] = -1;}mark[v] = 1;dis[v] = 0;int k = v;for(int i =1 ; i<n;i++){  //考察剩余的n-1个节点int min = Global.INF;for(int j = 0;j<n;j++){//找出本轮对应路径最短的节点if((mark[j]!=1)&&(dis[j]<min)){min = dis[j];k = j;}}mark[k] = 1;//将找出的最短路径对应的节点k加入集合S中for(int j =0;j<n;j++){//用上面新加入的节点k来更新dis[]if((mark[j]!=1)&&(A[k][j]<Global.INF)&&(min+A[k][j]<dis[j])){//不加A[k][j]<Global.INF的话,如果A[k][j]=Global.INF                             //min+A[k][j]就会得到一个很大的负数使得<dis[j]成立使程序出错dis[j] = min+A[k][j];path[j] = k ;}}}//打印for(int i =0;i<n;i++){if(i!=v){System.out.print("v"+v+"到v"+i+"的最短距离为:");if(mark[i]!=1){//if(!(dis[i]<Global.INF)){////System.out.print("无");System.out.print("无");}else{System.out.println(dis[i]);}//逆序打印路径方式,这次打印主要是为了看清楚path[]的作用,path[i]存储的是对应最短路径上的i的前驱结点if (mark[i] != -1) {// 存在最短路径System.out.print("v" + v + "到v" + i + "的最短路径为:");int prePath = i;while (prePath != v) {System.out.print(prePath + "<-");prePath = path[prePath];}System.out.println(v);}//正序打印路径的方式String pathStr = ""+i;String tmpStr = "";if (mark[i] != -1) {// 存在最短路径System.out.print("v" + v + "到v" + i + "的最短路径为:");int prePath = i;while (prePath != v) {//System.out.print(prePath + "<-");prePath = path[prePath];tmpStr = prePath + "->";pathStr = tmpStr + pathStr;}System.out.print(pathStr);}System.out.println("\n");}}}public static void computeShortestPathOfEachPairNodes(){int[][] A = {//测试{0,4,11},{6,0,2},{3,Global.INF,0}};int n = A[0].length;for(int i =0;i<n;i++){dijkstraShortestPath(i,A);}}public static void main(String[] args) {//floydShortestPath();int[][] A = {//测试{INF,INF, 10, INF, 30,100 },{INF,INF, 5,  INF, INF,INF},{INF,INF, INF,50,  INF,INF},{INF,INF, INF,INF, INF,10 },{INF,INF, INF,20,  INF,60 },{INF,INF, INF,INF, INF,INF},};int v0 = 0;//求解v0到各节点的最短路径dijkstraShortestPath(v0,A);//computeShortestPathOfEachPairNodes();//与Floyd做对比}}

测试结果:

                                          

0 0
原创粉丝点击