ダイクストラアルゴリズムとグラフの最短経路の幅優先探索


11

StackOverflowでこの質問をしました。ここに引っ越すように頼まれました。だからここにあります:

これらが正しい場合、ダイクストラのアルゴリズムと有向グラフでの幅優先検索に関するいくつかの説明と入力が必要です。

ダイクストラのアルゴリズムは、サイクルがあるかどうかに関係なく、重み付きグラフでAノードからノードへの最短経路を見つけますF(負の重みがない限り)。

しかし、そのためにAは、グラフ内の他のすべてのノードへのすべてのパスが計算AFれ、でノードのシーケンスを逆にすることで、からへのパスを取得しますprev

BFS:非加重グラフでAノードからノードへの最短パスを見つけFますが、サイクルが検出された場合は失敗します。

ただし、BFSはノードAからノードFへのパスを計算するだけで、必ずしもノードAからのすべてのパスを計算するわけではありません。ノードFに早く到達した場合は、パスを返すだけです。

グラフの例

回答:


17
  1. サイクルが検出されても、BFSは失敗しません。http://en.wikipedia.org/wiki/Breadth-first_search

  2. DijkstraはAからFへのすべてのパスも計算しません。AからFへの最短経路が見つかると停止します。

  3. 重み付けされていないグラフでは、BFSを使用して、Aから他のすべてのノードへの最短経路を同じ実行で検索することもできます。(Fを見つけたらすぐに停止させないでください)

  4. 長さnのすべてのエッジ(u、w)を置き換えることにより、すべての長さがO(k(v + e))時間の「小さい」数kより小さい整数であることがわかっている場合、BFSタイプアルゴリズムを使用して最短パスを見つけることができます。 uとwの間にn-1ノードのパスがある場合、パスの各エッジの長さは1です。

お役に立てれば。


あなたはポイント4手の込んだことができます
user1988876

@ User1988876:一般的なコメントとして、アディティアの返信に興味がある場合は、私が実際に行ったように、彼の回答に賛成することを強くお勧めします。これは通常、このようなサイトでは良い考えです。
カルロスリナレスロペス

1
返事が遅れて申し訳ありません。次のように、重みが小さい正の(k未満の)整数(u、v)であるグラフの任意のエッジを取ります。次のように、エッジuvをaaパスに置き換えますu-uv1-uv2-uv3-uv4-v( uv1からuv5は新しいノードです)、各エッジの重みは1です。すべてのエッジに対してこれを行います。結果のグラフのすべての重みが1になったので、<= k | v |の無向グラフと考えることができます。頂点および<= k | e | エッジ。BFSを使用して最短経路を見つけます。一般に、重みはグラフで任意に大きく、非積分にすることができるため、これはダイクストラよりも優れていません。
Aditya

6

Adityaの応答は良好ですが、いくつかの点を明確にしたいと思います。

幅優先検索

幅優先検索(BFS)は、キューを使用してノードをプッシュ/ポップするだけです。これは、深さの順にノードにアクセスすることを意味します。

すべての演算子のコストが同じである(それらが1と等しいと見なされる)場合は、最適なソリューションを見つけることが保証されます。

結果として、次の点に注意してください。

  1. ソリューションが最終的に見つかるまで、パスを列挙するだけです。このアルゴリズムは、ソースノードからゴールノードまでの最短経路(期間!)を計算するとは言えません。ゴールに向かう途中で遭遇するすべてのパスまでの距離を計算するだけです。言い換えると、目標ノードに到達するまでの経路について述べたことは、それによって発見された他の経路についても同様に言えます。

  2. 任意のコストのグラフにBFSが適用されるのを妨げるものはありません。唯一の注意点は、アルゴリズムが完全性を維持することで(解を見つけることが保証される)、許容性は失われます(つまり、解が最適であることを保証するわけではありません)。

  3. 元々、BFSは、すべての展開されたノードを格納するためのCLOSEDリストを考慮していなかったため、サイクルに該当する可能性があると言った場合、あなたは何とか正しいと言えます。ただし、すべてのノードを明示的にメモリに格納し、メモリを要求するレイヤーが常に最新のものになるため、BFSは通常、以前に展開されたすべてのノードを格納するCLOSEDリストで拡張されます。ノードを展開する前に転置が発生した場合は、安全にスキップできます。

ダイクストラのアルゴリズム

実際、上記のポイント3で提案されているようにCLOSEDリストをBFSに追加し、スタック内のノード(いわゆるOPENリスト)を昇順(つまり、 start state to)次に、ダイクストラのアルゴリズムがあります(まあ、別の非常に重要な違いもありますが、BFS はゴールノードの生成時に停止し、ダイクストラは展開時に停止ます)。g

そう:

  1. このアルゴリズムも、解が最終的に見つかるまでパスを列挙するだけです。状態空間内のすべてのノードを訪問することは事実ではありません。実際に、基礎となるグラフが無限大であっても、ダイクストラのアルゴリズムは完全であることがわかっています(つまり、解が存在する場合に解が見つかることを保証します)。

  2. オペレーションに任意のコストがかかる場合は、ダイクストラのアルゴリズムを安全に適用できます。実際、キューが、ノードがコストの昇順で挿入されるヒープに置き換えられたのはそのためです。

  3. Edgar Dijkstraは当初、閉止リスト(彼の論文を確認できます。数ページしかなく、非常に読みやすい)を使用することを検討していたため、サイクルが適切に考慮されました。

これがお役に立てば幸いですが、おそらくこれらのアルゴリズムのより詳細な説明が必要です。その場合は、遠慮なく依頼してください。

乾杯、


1
BFSはスタックではなくキューを使用します。
nbro 2015

@nbro:本当です!指摘してくれてありがとう!私はそれに応じて私の回答を編集して修正しました!
カルロスリナレスロペス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.