22

我一直在研究这三个,我在下面陈述我的推论。有人能告诉我我是否足够准确地理解它们吗?谢谢你。

  1. Dijkstra 算法仅在您有单一来源并且您想知道从一个节点到另一个节点的最小路径时使用,但在这种情况下会失败

  2. 当所有节点中的任何一个都可以成为源时,使用 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"

迪杰斯特拉:

 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;

弗洛伊德-沃歇尔:

 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] );
4

2 回答 2

21

您对前两个问题以及 Floyd-Warshall 的目标(找到所有对之间的最短路径)是正确的,但对于 Bellman-Ford 和 Floyd-Warshall 之间的关系却不是:两种算法都使用动态规划来找到最短路径路径,但 FW 与从每个起始节点到每个其他节点运行 BF 不同。

在BF中,问题是:最多k步从源到目标的最短路径是多少,运行时间为O(E V)。如果我们将它运行到其他节点,运行时间将是 O(E V^2)。

在 FW 中,问题是:对于所有节点 i,j,k,从 i 到 j 通过 k 的最短路径是什么。这导致 O(V^3) 运行时间 - 每个起始节点都比 BF 好(对于密集图,高达 |V| 的因子)。

关于负循环/权重的另一个注意事项:Dijkstra 可能根本无法给出正确的结果。BF 和 FW 不会失败——它们会正确地声明没有最小权重路径,因为负权重是无界的。

于 2012-07-28T21:23:03.843 回答
9

单源最短路径:

Dijkstra 算法 - 不允许负权重 - O(E+Vlg(V))

贝尔曼福特算法 - 允许负重。但如果存在负循环,贝尔曼福特将检测到 -ve 循环 - O(VE)

有向无环图 - 顾名思义,它仅适用于 DAG - O(V+E)

所有对最短路径:

Dijkstra 算法 - 不允许负权重 - O(VE + V^2lg(V))

贝尔曼福特算法 - O(V^2E)

矩阵链乘法——复杂度与贝尔曼福特算法相同

Floyd Warshall 算法 - 使用动态规划方法 - 复杂度为 O(V^3)

于 2012-07-29T10:05:36.160 回答