有向图的单源非负最短路径算法-dijkstra算法

Posted zqiguoshang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有向图的单源非负最短路径算法-dijkstra算法相关的知识,希望对你有一定的参考价值。

dijkstra应用范围:

图中各边权值非负。

最短路径在现实中应用很广,比如在地图上找出最短路径等,这个算法很重要。

算法思想很简单,它不是找特定节点対之间的最短路径,它是找出源节点到所有其他节点的最短路径。

怎么找呢?

所需额外参数:path[] 记录路径。 dist[] 记录路径长度, visited [] 标记已找到最短路径的节点。

第一步初始化,

将源节点visited标记为true, 并将其直连边长度,更新到dist[]数组。

 

其次要明白所有路径中最短的路径是哪一条?

肯定是源节点直连边(路径长度为1)中最短的那一条。

第二条呢?

必然是直连边或者第一条最短路径再扩一边中的最小边。

第N条呢?

如果我们把以求出最短路径的点标记为true,那么可以证明,下一条最短路径必然是true点再扩一条边中的最短边所组成的路径。

然后我们依次找下去,找N-1次,就可以找到源节点到所有目标节点的最短路径。

想要找出所有节点间的最短路径,变换源节点,重复N次即可。

下面给出Java代码,图用邻接矩阵存储:

 1 public int minPath(int source, int target){
 2         if (source == target){
 3             System.out.println("(" + source + " " + target + ")");
 4             return 0;
 5         }
 6         int[] path = dijkstra(source);
 7         int result = 0;
 8         String way = "";
 9         while (-1 != path[target]){
10             way = "(" + path[target] + " " + target + ") " + way;
11             result += graph[path[target]][target];
12             target = path[target];
13         }
14         System.out.println(way);
15         return result;
16     }
17     private int[] dijkstra(int vertex){
18        int[] path = new int[numVertices];
19        boolean[] visited = new boolean[numVertices];
20        int[] lenPath = new int[numVertices];
21 
22        // initial
23        int neighbor = getFirstNeighbor(vertex);
24        while (neighbor != -1){
25            lenPath[neighbor] = graph[vertex][neighbor];
26            neighbor = getNextNeighbor(vertex,neighbor);
27        }
28        for (int i = 0; i < numVertices; i++) {
29            if (lenPath[i] == 0){
30                lenPath[i] = 1000;
31                path[i] = -1;
32            }else{
33                path[i] = vertex;
34            }
35        }
36        visited[vertex] = true;
37 
38         // find min pathLen in unvisited vertex.
39        for (int i = 0; i < numVertices-1; i++) {
40            int min = vertex;
41            for (int j = 0; j < numVertices; j++) {
42                if (visited[j] == false && lenPath[j] < lenPath[min]){
43                    min = j;
44                }
45            }
46            if (min == vertex){
47                return path;
48            }
49            visited[min] = true;
50            for (int j = 0; j < numVertices; j++) {
51                if (visited[j] == false && lenPath[j] > lenPath[min] + graph[min][j]){
52                    lenPath[j] = lenPath[min] + graph[min][j];
53                    path[j] = min;
54                }
55            }
56        }
57        return path;
58     }

 

以上是关于有向图的单源非负最短路径算法-dijkstra算法的主要内容,如果未能解决你的问题,请参考以下文章

Dijkstra 的单源最短路径算法能否检测到图中的无限循环?

Bellman-ford 单源最短路径算法

最短路径 Dijkstra 算法为啥边上的权值非负阿?

Dijkstra算法

图中最短路径算法(Dijkstra算法)(转)

最短路径—Dijkstra算法