Подтвердить что ты не робот

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

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

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

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

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

3.Bellman-Ford используется как Dijkstra, когда есть только один источник. Это может обрабатывать отрицательные веса, а его работа такая же, как у Floyd-Warshall, за исключением одного источника, правильно?

Если вам нужно взглянуть, соответствующие алгоритмы (любезность 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] );
4b9b3361

Ответ 1

Вы правы в первых двух вопросах и о цели Флойда-Варшалла (поиск кратчайших путей между всеми парами), но не о взаимосвязи между Bellman-Ford и Floyd-Warshall: оба алгоритма используют динамическое программирование для найдите кратчайший путь, но FW не совпадает с запуском BF от каждого запуска node ко всем другим node.

В BF возникает вопрос: каков самый короткий путь от источника к цели с использованием не более k шагов, а время работы - O (EV). Если мы будем запускать его друг с другом node, время выполнения будет равно O (EV ^ 2).

В FW возникает вопрос: каков самый короткий путь от я до j через k, для всех узлов i, j, k. Это приводит к времени работы O (V ^ 3) - лучше, чем BF для каждого пуска node (в процентах до | V | для плотных графов).

Еще одно замечание об отрицательных циклах/весах: Дейкстра может просто не дать правильных результатов. BF и FW не сбой - они будут правильно заявлять, что нет минимального пути веса, так как отрицательный вес неограничен.

Ответ 2

Кратчайшие пути с одним источником:

Dijkstra Algorithm - Без отрицательного веса - O (E + Vlg (V))

Алгоритм Bellman ford - допустимый отрицательный вес. Но если присутствует отрицательный цикл, то Bellman ford будет определять цикл -ve-O (VE)

Направленный ациклический график - как следует из названия, он работает только для DAG-O (V + E)

Все пары кратчайших путей:

Dijkstra Algorithm - отрицательный вес не допускается - O (VE + V ^ 2lg (V))

Алгоритм Беллмана-Форда - O (V ^ 2E)

Метод умножения матричной цепочки -комплексность такая же, как алгоритм Bellman ford

Алгоритм Флойда Варшалла - использует метод динамического программирования - Сложность - это O (V ^ 3)