幅優先探索

グラフトラバーサル

グラフトラバーサルとは、ウェル内のすべての頂点とエッジに1回だけアクセスすることを意味します。 -定義された順序。特定のグラフアルゴリズムを使用している間は、グラフの各頂点に1回だけアクセスする必要があります。頂点にアクセスする順序は重要であり、解決するアルゴリズムまたは質問によって異なる場合があります。

トラバーサル中は、どの頂点にアクセスしたかを追跡することが重要です。頂点を追跡する最も一般的な方法は、頂点にマークを付けることです。

幅優先探索(BFS)

グラフを走査する方法はたくさんあります。 BFSは最も一般的に使用されるアプローチです。

BFSはトラバースアルゴリズムであり、選択したノード(ソースノードまたは開始ノード)からトラバースを開始し、グラフをレイヤーごとにトラバースして、隣接ノード(ソースノードに直接接続されているノード)を探索する必要があります。次に、次のレベルの隣接ノードに向かって移動する必要があります。

BFSの名前が示すように、次のようにグラフを横方向にトラバースする必要があります。

  1. 最初に水平に移動し、現在のレイヤーのすべてのノードにアクセスします
  2. 次のレイヤーに移動します

次の図を検討してください。

レイヤー1のノード間の距離は、レイヤー2のノード間の距離よりも比較的小さいため、BFSでは、レイヤー2のノードに移動する前に、レイヤー1のすべてのノードをトラバースする必要があります。

子ノードのトラバース

グラフにはサイクルを含めることができます。これにより、グラフをトラバースしているときに同じノードに再び移動する場合があります。同じノードが再度処理されないようにするには、処理後にノードをマークするブール配列を使用します。グラフのレイヤー内のノードにアクセスするときは、対応する子ノードを同様の順序でトラバースできるようにノードを格納します。

このプロセスを簡単にするには、キューを使用してノードを保存し、すべての隣接ノード(ノードに直接接続されている頂点)がマークされるまで、ノードを「訪問済み」としてマークします。キューは先入れ先出し(FIFO)キューイング方式に従うため、ノードのネイバーはノードに挿入された順序でアクセスされます。つまり、最初に挿入されたノードが最初にアクセスされます。オン。

擬似コード

トラバースプロセス

トラバースソースノードから開始し、sをキューにプッシュします。 sは「訪問済み」としてマークされます。

最初の反復

  • はキューからポップされます
  • sの隣人、つまり1と2がトラバースされます
  • 以前にトラバースされていない1と2がトラバースされます。
    • キューにプッシュされます
    • 1と2は訪問済みとしてマークされます

2回目の反復

  • 1がキューからポップされます
  • 1のネイバー、つまりsと3がトラバースされます
  • sは「訪問済み」としてマークされているため、無視されます
  • 3は以前にトラバースされていませんがトラバースされます。
    • キューにプッシュされました
    • 訪問済みとしてマークされました

3回目の反復

  • 2がキューからポップされます
  • 2のネイバー、つまりs、3、および4がトラバースされます
  • 3およびsは、「訪問済み」としてマークされているため無視されます
  • 4は、以前にトラバースされていませんが、トラバースされます。
    • キューにプッシュされました
    • 訪問済みとしてマークされました

4回目の反復

  • 3がキューからポップされます
  • 3のネイバー、つまり1、2、および5がトラバースされます
  • 1および2は、「訪問済み」としてマークされているため無視されます
  • 5は、以前にトラバースされていませんが、トラバースされます。
    • キューにプッシュされました
    • 訪問済みとしてマークされました

5回目の反復

  • 4はキューからポップされます
  • 4のネイバー、つまり2がトラバースされます
  • 2はすでに「訪問済み」としてマークされているため、無視されます

6回目の反復

  • 5がキューからポップされます
  • 5のネイバー、つまり3がトラバースされます
  • 3は無視されます。すでに「訪問済み」としてマークされています

キューは空であり、ループから抜け出します。すべてのノードはBFSを使用してトラバースされています。

グラフ内のすべてのエッジが同じ重みである場合、BFSを使用してグラフ内のノード間の最小距離を見つけることもできます。

この図のように、ソースノードから開始して、ソース間の距離を見つけますノードとノード1。BFSアルゴリズムに従わない場合は、ソースノードからノード2、次にノード1に移動できます。このアプローチでは、ソースノードとノード1の間の距離が2として計算されますが、最小値は距離は実際には1です。最小距離は、BFSアルゴリズムを使用して正しく計算できます。

複雑さ

BFSの時間計算量はO(V + E)です。ここで、Vはノードの数、Eはエッジの数です。

アプリケーション

1。特定のツリーの各ノードのレベルを決定する方法は?

BFSで知っているように、レベルごとにトラバースします。 BFSを使用して、各ノードのレベルを決定することもできます。

実装

このコードはBFSコードに似ていますが、次の違いがあります。
level] = level + 1;

このコードでは、各ノードにアクセスしている間、そのノードのレベルは、その親ノードのレベルの増分で設定されます。これが各ノードのレベルの決定方法です。

2 。 0-1 BFS

このタイプのBFSは、グラフのエッジの重みが0または1の場合に、グラフ内の2つのノード間の最短距離を見つけるために使用されます。前に説明したBFSを適用する場合この記事では、2つのノード間の最適な距離に対して誤った結果が得られます。

このアプローチでは、最適な距離の条件がチェックされるため、ノードをマークするためにブール配列は使用されません。各ノードにアクセスします。両端キューは、ノードを格納するために使用されます。 0-1 BFSでは、エッジの重みが0の場合、ノードはデキューの先頭にプッシュされます。エッジの重みが1の場合、ノードはデキューの後ろにプッシュされます。

実装

Qは両端キューです。 distanceは配列であり、distanceには開始ノードからvノードまでの距離が含まれます。最初、ソースノードから各ノードまでに定義された距離は無限大です。

次のグラフでこのコードを理解しましょう:

グラフの隣接リストは次のようになります。
ここで、「s」は0またはソースノードと見なされます。

0- > 1- > 3- > 2
Edges.first = 1、edges.second = 1
edges.first = 3、edges.second = 0
Edges.first = 2、edges.second = 1

1 -> 0- > 4
edges.first = 0、edges.second = 1
Edges.first = 4 、edges.second = 0

2- > 0- > 3
Edges.first = 0 、edges.second = 0
Edges.first = 3、edges.second = 0

3- > 0- > 2- > 4
edges.first = 0、edges.second = 0
Edges.first = 2、edges.second = 0
Edges.first = 4、edges.second = 0

4- > 1- > 3
Edges.first = 1、edges.second = 0
Edges.first = 3、edges.second = 0

BFSアルゴリズムを使用すると、結果が不正確になります。 s間の最適な距離ノード1とsおよびノード2をそれぞれ1として。これは、sの子を訪問し、sとその子の間の距離(1)を計算するためです。実際の最適距離はどちらの場合も0です。

処理

ソースノード、つまり0から開始して、1、2、および3に向かって移動します。0と1の間および0と2の間のエッジの重みはそれぞれ1であるため、1および2はキューの最後にプッシュされます。ただし、0と3の間のエッジの重みは0であるため、3はキューの先頭にプッシュされます。距離はそれに応じて距離配列で維持されます。

3がキューからポップされ、同じプロセスが隣接するものに適用されます。

投稿者: Prateek Garg

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です