web-dev-qa-db-ja.com

幅優先探索に対する深さ優先探索の利点、またはその逆。

深さ優先探索と幅優先探索の2つのグラフ探索アルゴリズムを研究しました。どちらのアルゴリズムもグラフ探索の同じ問題を解決するために使用されるため、2つのアルゴリズムのどちらを選択するかを知りたいと思います。特定のシナリオで他の理由または他の理由を選択する理由は何ですか?

ありがとうございました

16
Kris

私との主な違いはやや理論的です。無限のサイズのグラフがある場合、DFSは、選択した最初のパスの外側に要素が存在する場合、その要素を見つけることはありません。それは本質的に最初の道を進み続け、要素を見つけることは決してありません。 BFSは最終的に要素を見つけます。

グラフのサイズが有限である場合、DFSは外れ値(ルートとゴールの間の距離が大きい)要素をより速く検出し、BFSはより近い要素をより速く検出する可能性があります。 DFSが浅い要素のパスを選択する場合を除きます。

9
Justin

一般に、BFSは、最短パスの検索に関連する問題、またはある程度関連する問題に適しています。ここでは、1つのノードからそれに隣接するすべてのノードに移動するため、パスの長さ1からパスの長さ2に効果的に移動します。

一方、もう一方の端のDFSは、接続の問題やグラフ内のサイクルの検索に役立ちます(ただし、BFSを少し変更するだけでサイクルを見つけることができると思います)。 DFSとの接続性を判断するのは簡単です。DFSプロシージャからexploreプロシージャを2回呼び出すと、グラフが切断されます(これは無向グラフの場合です)。 DFSの変更である、有向グラフの強連結成分アルゴリズムをここで確認できます。 DFSのもう1つのアプリケーションは、トポロジカルソートです。

これらは両方のアルゴリズムのいくつかのアプリケーションです:

DFS:

接続性
強く接続されたコンポーネント
トポロジカルソート

BFS:

最短経路(ダイクストラはBFSの修正のようなものです)。
グラフが二者間であるかどうかをテストします。

7
sukunrt

完全/完全なツリーの場合、DFSはツリーの深さに関して線形量のスペースを取りますが、BFSはツリーの深さに関して指数関数的な量のスペースを取ります。これは、BFSの場合、キュー内のノードの最大数がツリーの1つのレベル内のノード数に比例するためです。 DFSでは、スタック内のノードの最大数はツリーの深さに比例します。

0
Kevin Wheeler

多重接続されたグラフをトラバースする場合、ノードがトラバースされる順序は、トラバース方法によって追跡されるノードの数に大きく影響する可能性があります(桁違いに)。幅優先を使用すると、一部の種類のアルゴリズムが大幅に向上します。深さ検索を使用すると、他のものが大幅に改善されます。

極端な例として、N個のリーフノードを持つバイナリツリーで深度優先検索を実行するには、トラバース方法でlgNノードを追跡する必要がありますが、幅優先検索では、少なくともN/2ノードを追跡する必要があります(スキャンする可能性があるため)。リーフノードをスキャンする前の他のすべてのノード。最初のリーフノードをスキャンする直前に、リーフの親ノードのN/2に遭遇しました。これらのノードは相互に参照していないため、個別に追跡する必要があります。

もう一方の極端な例として、NxNグリッドで、ピクセルがまだ色付けされていない場合にそのピクセルに色を付けてから隣接するピクセルを塗りつぶす方法でフラッドフィルを実行するには、キューイングが必要になりますO(N)幅優先探索を使用する場合はピクセル座標、深さ優先探索を使用する場合はO(N ^ 2)ピクセル座標。幅優先探索を使用する場合、ペイントは形状に関係なく「広がる」ように見えます。深さ優先アルゴリズムを使用して、各線が片側が直線で反対側がギザギザになっている長方形のスパイラルを塗る場合(使用する正確なアルゴリズムによって、どの辺が真っ直ぐでギザギザになるかによって異なります)、すべての直線セクションギザギザの前にペイントされます。つまり、システムはすべてのジャグの位置を個別に追跡する必要があります。

0
supercat