Floyd-Warshall、Dijkstraのアルゴリズム、Bellman-Fordアルゴリズムの違いについては正しいですか?


12

私は3つを研究しており、それらからの推論を以下に述べています。それらを十分に正確に理解しているかどうかを誰かに教えてもらえますか?ありがとうございました。

  1. ダイクストラのアルゴリズムは、単一のソースがあり、あるノードから別のノードへの最小パスを知りたい場合にのみ使用されますが、このような場合は失敗します

  2. Floyd-Warshallのアルゴリズムは、すべてのノードのいずれかがソースになる可能性がある場合に使用されるため、ソースノードから宛先ノードに到達する最短距離が必要です。これは、負のサイクルがある場合にのみ失敗します

(これは最も重要なものです。つまり、これは私が最も確信していないものです:)

3.Bellman-Fordは、ソースが1つしかない場合のダイクストラのように使用されます。これは負の重みを処理でき、その動作は1つのソースを除き、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] );

Dijkstraのアルゴリズムは負の重みのノードを処理できると確信しています。負の重みのサイクルがある場合、最短経路はアルゴリズムに関係なく未定義です。
ケビンクライン

1
@kevincline:ウィキペディアはあなたの主張をサポートしていません(ウィキペディアが正しいと主張していないのですが、AlgTheoryの本は数百マイル先にあります)しかし、実際の時間ベースまたは速度ベースのルーティングの問題はありますネガティブエッジがないため、通常、必要に応じて、ダイスクトラまたはフロイドを実行します。私が覚えている限り、ほとんどの実際の地図作成ルーティングアルゴリズムは、Dijsktraの最新版に基づいていますが、以前の職場で読んだ科学論文から覚えています。
-Aadaam

@Aadaam:私は間違っています。ダイクストラは非負性を利用して、すべてのエッジを訪問することを避けています。
ケビンクライン

はい、あなたは正しく理解しました。:)
サンヒョン

回答:


3

私があなたを正しく理解していれば、あなたの理解は正しいです。

  • Djikstra'sは、負の重みエッジがある場合を除き、グラフ内のソースノードから他のすべてのノードへの最小コストパスを検索します。(Dijkstraは、ターゲットノードが見つかったら停止するように変更し、ヒューリスティックを追加するだけで、A *アルゴリズムに簡単に変換できます。)
  • ベルマン・フォードはダイクストラと同じことをしますが、遅いです。ただし、負の重みのエッジは処理できます。
  • Floyd-Warshallは、各ノードから他のすべてのノードへの最小コストパスのコストを見つけます。(数値行列を返します。)ジクストラまたはベルマンフォードよりもはるかに遅いです。あなたが書いたものとは異なり、負のサイクルが発生しても失敗せず、ノード自体のコストに対して無意味な負の数を報告するだけです。

1
いや、フロイドワーシャルは、パスの長さだけでなく、ジクストラやベルマンフォードと同じように、パス自体を計算できます。
コンラッドルドルフ

もちろん、修正あり。
シーザーバウティスタ

3
ターゲットノードで停止した場合、最初のものはまだダイクストラのものであると考えますが、ヒューリスティックを使用しませんでした。
エリオットボール

1
@CSA-フロイドウォーシャルはO(n ^ 3)であるため、このような大きなグラフには約10 ^ 300の操作が必要になります。各操作がプランク時間を要すると仮定すると、計算が終了するまでに、宇宙の通常の物質のすべての陽子が崩壊し、超大質量ブラックホールのみが残ります。内部ループを並列化できる可能性があると思います。これが本当なら、太陽の塊で始まったすべてのブラックホールが蒸発する前に終了するのに十分幸運かもしれません。
ジュール

1
(あなたは、プロセスごとに以下の一つの原子を用いた処理ノードを構築することができ、かつある観測可能な宇宙、中の原子のすべてを使用することができると仮定すると...しかし、あなたはおそらくで始めるためにあなたのデータを格納するために、それらのすべてを必要とします)
ジュール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.