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


12

Я вивчав три, і я викладаю свої висновки з них нижче. Чи міг би хтось сказати мені, чи достатньо точно я їх зрозумів чи ні? Дякую.

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

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

(це найважливіше. Я маю на увазі, це саме те, про що я найменш впевнений :)

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

Якщо вам потрібно подивитися, відповідні алгоритми (люб’язно надана Вікіпедія):

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

 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;

Флойд-Варшалл:

 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, але я просто пам’ятаю це з деяких наукових праць, які я читав на своєму попередньому робочому місці.
Аадаам

@Aadaam: Я помиляюся. Dijkstra використовує негативність, щоб уникнути відвідування кожного краю.
кевін клайн

Так, ви правильно зрозуміли. :)
Sanghyun Lee

Відповіді:


3

Якщо я вас правильно зрозумів, ваше розуміння правильно.

  • Джикстра знаходить шлях найменшої вартості від вузла джерела до кожного іншого вузла в графі, за винятком випадків, коли є межа негативної ваги. (Дійкстра можна легко перетворити в алгоритм A *, просто змінивши його, щоб зупинити, як тільки він знайде цільовий вузол, і додавши евристику.)
  • Bellman-Ford робить те саме, що і у Dijkstra, але повільніше. Але він може обробляти негативні ваги.
  • Флойд-Варшалл знаходить вартість найменшого шляху витрат від кожного вузла до кожного іншого вузла. (Він повертає числову матрицю.) Це набагато повільніше, ніж або Джикстра, або Беллман-Форд. На відміну від написаного вами, він не виходить з ладу, коли виникає негативний цикл, він просто повідомляє про себе безглузде від’ємне число за вартість деякого вузла.

1
Так, Флойд-Варшалл може обчислити самі шляхи, як і Джикстра і Беллман-Форд, а не лише довжини шляху.
Конрад Рудольф

З модифікаціями, звичайно.
Ceasar Bautista

3
Я все-таки вважав би першим діжкстра, якби він був зупинений на цільовому вузлі, але не використовував евристику.
Eliot Ball

1
@CSA - Floyd Warshall - це O (n ^ 3), тож для такого великого графіка потрібно буде близько 10 ^ 300 операцій. Якщо припустити, що кожна операція потребує часу Планка, до моменту закінчення обчислення всі протони у звичайній речовині у Всесвіті затухнуть, і залишиться лише надмасивна чорна діра . Я вважаю, що можливо паралелізувати внутрішню петлю. Якщо це правда, можливо, вам пощастить закінчити, перш ніж всі чорні діри, що почалися з маси сонця, випарувалися.
Жуль

1
(Якщо припустити, що ви можете створити вузол обробки, використовуючи менше одного атома за процес, і можете використовувати всі атоми у спостережуваному Всесвіті, тобто ... але тоді, ймовірно, вам знадобляться всі, для зберігання ваших даних для початку)
Жуль
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.