我一直在研究这三个,并在下面说明了他们的推论。有人可以告诉我我是否足够正确地理解它们?谢谢。
Dijkstra的算法仅在您只有一个来源并且想知道从一个节点到另一个节点的最小路径时使用,但是在这种情况下会失败
当所有节点中的任何一个都可以作为源时,将使用Floyd-Warshall算法,因此您希望从任何源节点到任何目标节点的距离最短。仅在出现负循环时失败
(这是最重要的一个。我的意思是,这是我最不确定的一个:)
3,贝尔曼·福特(Bellman-Ford)和迪杰斯特拉(Dijkstra)一样,只有一个来源。它可以处理负数权重,其工作方式与Floyd-Warshall相同,只是有一个来源,对吗?
如果需要看一下,相应的算法是(由维基百科提供):
贝尔曼福特:
procedure BellmanFord(list vertices, list edges, vertex source)
// This implementation takes in a graph, represented as lists of vertices
// and edges, and modifies the vertices so that their distance and
// predecessor attributes store the shortest paths.
// Step 1: initialize graph
for each vertex v in vertices:
if v is source then v.distance := 0
else v.distance := infinity
v.predecessor := null
// Step 2: relax edges repeatedly
for i from 1 to size(vertices)-1:
for each edge uv in edges: // uv is the edge from u to v
u := uv.source
v := uv.destination
if u.distance + uv.weight < v.distance:
v.distance := u.distance + uv.weight
v.predecessor := u
// Step 3: check for negative-weight cycles
for each edge uv in edges:
u := uv.source
v := uv.destination
if u.distance + uv.weight < v.distance:
error "Graph contains a negative-weight cycle"
Dijkstra:
1 function Dijkstra(Graph, source):
2 for each vertex v in Graph: // Initializations
3 dist[v] := infinity ; // Unknown distance function from
4 // source to v
5 previous[v] := undefined ; // Previous node in optimal path
6 // from source
7
8 dist[source] := 0 ; // Distance from source to source
9 Q := the set of all nodes in Graph ; // All nodes in the graph are
10 // unoptimized - thus are in Q
11 while Q is not empty: // The main loop
12 u := vertex in Q with smallest distance in dist[] ; // Start node in first case
13 if dist[u] = infinity:
14 break ; // all remaining vertices are
15 // inaccessible from source
16
17 remove u from Q ;
18 for each neighbor v of u: // where v has not yet been
19 removed from Q.
20 alt := dist[u] + dist_between(u, v) ;
21 if alt < dist[v]: // Relax (u,v,a)
22 dist[v] := alt ;
23 previous[v] := u ;
24 decrease-key v in Q; // Reorder v in the Queue
25 return dist;
弗洛伊德·沃希尔(Floyd-Warshall):
1 /* Assume a function edgeCost(i,j) which returns the cost of the edge from i to j
2 (infinity if there is none).
3 Also assume that n is the number of vertices and edgeCost(i,i) = 0
4 */
5
6 int path[][];
7 /* A 2-dimensional matrix. At each step in the algorithm, path[i][j] is the shortest path
8 from i to j using intermediate vertices (1..k−1). Each path[i][j] is initialized to
9 edgeCost(i,j).
10 */
11
12 procedure FloydWarshall ()
13 for k := 1 to n
14 for i := 1 to n
15 for j := 1 to n
16 path[i][j] = min ( path[i][j], path[i][k]+path[k][j] );
我很确定Dijkstra的算法可以处理负重量节点。如果存在负权重循环,则无论采用哪种算法,最短路径都是不确定的。
—
凯文·克莱恩
@kevincline:Wikipedia不支持您的主张(尽管我不认为Wikipedia是正确的,而且我的AlgTheory书距离我们只有几百英里),但是,在现实中基于时间或基于速度的路由问题中存在没有负面影响,因此我通常根据需要进行Dijsktra或Floyd的测试。据我所知,大多数现实中的制图路由算法都是基于Dijsktra的现代化版本,但是我只是从我在以前工作场所阅读的一些科学论文中就记住了这一点。
—
Aadaam
@Aadaam:我错了。Dijkstra利用非负性来避免访问每个边缘。
—
凯文·克莱恩
是的,您理解正确。:)
—
Sanghyun Lee 2012年