Прав ли я относительно различий между алгоритмами Флойда-Варшалла, Дейкстры и Беллмана-Форда?

12

Я изучал эти три, и я излагаю свои выводы из них ниже. Может ли кто-нибудь сказать мне, достаточно ли я их понял, или нет? Спасибо.

  1. Алгоритм Дейкстры используется только тогда , когда у вас есть один источник , и вы хотите знать , наименьший путь от одного узла к другому, но не может в таких случаях , как это

  2. Алгоритм Флойда-Варшалла используется, когда любой из всех узлов может быть источником, поэтому вы хотите, чтобы кратчайшее расстояние достигло любого узла назначения из любого узла-источника. Это терпит неудачу только при наличии отрицательных циклов

(это самый важный. Я имею в виду, в этом я меньше всего уверен :)

3. Беллман-Форд используется как Дейкстра, когда есть только один источник. Это может обрабатывать отрицательные веса, и его работа такая же, как у Флойд-Варшалла, за исключением одного источника, верно?

Если вам нужно посмотреть, соответствующие алгоритмы (любезно предоставленные Wikipedia):

Беллмана-Форда:

 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] );
Программирование нуб
источник
Я уверен, что алгоритм Дейкстры может обрабатывать узлы с отрицательным весом. Если есть циклы с отрицательным весом, кратчайший путь не определен, независимо от алгоритма.
Кевин Клайн
1
@kevincline: Википедия не поддерживает ваше заявление (хотя я не утверждаю, что Википедия права, и у меня есть книга AlgTheory за несколько сотен миль). Однако в реальной жизни или на основе скорости возникают проблемы с маршрутизацией. нет отрицательных краев, поэтому я обычно делаю Dijsktra или Floyd, в зависимости от необходимости. Насколько я помню, большинство реальных картографических алгоритмов маршрутизации основаны на модернизированной версии Dijsktra, но я только помню это из некоторых научных работ, которые я читал на моем предыдущем рабочем месте.
Аадам
@ Аадам: я не прав. Дейкстра использует неотрицательность, чтобы избежать посещения каждого края.
Кевин Клайн
Да, вы правильно поняли. :)
Sanghyun Lee

Ответы:

3

Если я вас правильно понимаю, ваше понимание верно.

  • Djikstra's находит путь наименьшей стоимости от исходного узла до каждого другого узла в графе, кроме случаев, когда есть отрицательный весовой фронт. (Dijkstra's можно легко преобразовать в алгоритм A *, просто изменив его для остановки, как только он найдет целевой узел, и добавив эвристику.)
  • Беллман-Форд делает то же самое, что и Дейкстра, но медленнее. Но он может обрабатывать края с отрицательным весом.
  • Floyd-Warshall находит стоимость пути наименьшей стоимости от каждого узла до каждого другого узла. (Возвращает числовую матрицу.) Это намного медленнее, чем у Джикстры или Беллмана-Форда. В отличие от того, что вы написали, он не терпит неудачу при возникновении отрицательного цикла, он просто сообщает бессмысленное отрицательное число для стоимости некоторого узла для себя.
Цезарь Баутиста
источник
1
Нет, Флойд-Варшалл может вычислять сами пути, так же как Джикстра и Беллман-Форд, а не только длины пути.
Конрад Рудольф
С модификациями, конечно.
Цезарь Баутиста
3
Я бы по-прежнему считал первым Dijkstra, если бы он был остановлен на целевом узле, но не использовал эвристику.
Элиот Болл
1
@CSA - Флойд Варшалл - это O (n ^ 3), поэтому для такого большого графа потребуется около 10 300 операций. Предполагая, что каждая операция занимает время Планка, к тому времени, когда вычисление закончится, все протоны в обычном веществе во вселенной распадутся, и останутся только сверхмассивные черные дыры . Я полагаю, что возможно распараллелить внутренний цикл. Если это правда, возможно, вам повезет закончить до того, как все черные дыры, образовавшиеся под действием массы Солнца, испарились.
Жюль
1
(Предполагая, что вы можете построить узел обработки, используя менее одного атома на процесс, и можете использовать все атомы в наблюдаемой вселенной, то есть ... но тогда вам, вероятно, понадобятся все из них для хранения ваших данных, чтобы начать с)
Жюль