グラフの深さ優先検索におけるグレーノードの目的


18

私が見た深さ優先検索の多くの実装(例:ここ)では、コードは灰色の頂点(発見されたが、そのすべての隣人が訪問されたわけではない)と黒の頂点(発見され、そのすべての隣人が訪問された)を区別します。この区別の目的は何ですか?DFSアルゴリズムは、グレーであるか黒であるかに関係なく、訪問先の頂点にアクセスすることはないようです。

回答:


25

DFSを実行するとき、ノードは3つの状態のいずれかになります-訪問される前、子孫を再帰的に訪問している間、およびすべての子孫が訪問された後(親に戻る、つまり後処理段階)。3つの色は、3つの状態のそれぞれに対応しています。色と訪問と戻りの時間に言及する理由の1つは、理解を深めるためにこれらの区別を明示的に行うことです。

もちろん、これらの色の実際の用途があります。有向グラフ考えます。のサイクルの存在をチェックするとします。無向グラフでは、検討中のノードに黒または灰色の隣接がある場合、サイクルを示します(そして、DFSはあなたが言及したようにそれを訪問しません)。しかし、の場合に方向付けグラフ、ブラック隣接サイクルを意味するものではありません。たとえば、3つの頂点およびを持ち、、、ような有向エッジを持つグラフを考えます。DFSがで始まり、次に、次にアクセスするとします。に戻ったときGGA,B,CABBCACABCA、次にが既にアクセスされており、黒であることを確認します。しかし、グラフにはサイクルがありません。C

有向グラフでは、すべての子孫が訪問される前にノードが再び表示される場合にのみ、サイクルが存在します。言い換えると、ノードにグレーのネイバーがある場合、サイクルがあります(ネイバーが黒の場合ではありません)。灰色のノードは、現在その子孫を探索していることを意味します。そのような子孫の1つがこの灰色のノードへのエッジを持っている場合、サイクルがあります。したがって、有向グラフでのサイクル検出には、3色が必要です。他の例もありますが、あなたはアイデアを得る必要があります。


2
+1良い説明。無向グラフ(質問本文にリンクされているグラフなど)のすべてのノードを単純にトラバースするには、GRAYとBLACKに機能的な違いはありませんか?
user6805

1
@ user6805有向グラフと無向グラフの両方の単純なトラバーサル(すべてのノードの訪問)の場合、グレーと黒の間に機能的な違いはありません。使用できるのは2色のみです(または訪問済み/未訪問)。色が必要なのは、より複雑なアルゴリズム用です。
Paresh

私はそれを理解しました!OK、次のケースを考えてみましょう:twitter.com/MaksimADmitriev/status/796995958043279361 DFSを使用してグラフを走査します。左側のグラフはこの回答のグラフと同じであり、サイクルはありません。サイクルのある右側のグラフをトラバースしましょう。Aにアクセスし、グレーにマークします。Bにアクセスし、グレーにマークします。Cにアクセスして、灰色にマークします。今、私たちはすでに灰色になっているAに行きます。したがって、「黒から黒へ」はサイクルがあることを意味しませんが、「グレーからグレーへ」はサイクルがあることを意味します。それがグレーが必要な理由です。私が間違っている場合は修正してください
Maksim Dmitriev

強力に接続されたコンポーネントの検索など、さらに複雑な目的のために、ノードごとに2回記録する必要があります。 (つまり、黒い色になった時間)。記録を実装するために、各イベントが発生するたびに増加するカウンターが維持されます。
ジョン

2

CLRSの演習では、グレーまたはブラックの色を削除することができ、アルゴリズムは2色だけで正常に機能します。つまり、実際には必要ありません。頂点をマークする主な目的は、既に訪れた頂点を繰り返し訪れて、無限ループに陥らないようにすることです。

DFSアルゴリズムで3色を使用する理由は主に教育的です。概念的に明確であり、各ノードの実行中に何が起こっているかを学生が確認するのに役立ちます。


0

灰色の頂点は、そのノードを訪問し、あるノードの隣のノードに移動したことを示していますが、そのノードにはさらに多くの隣接する頂点がある可能性があります。これは、未訪問の頂点を探索するためのバックトラッキング中に役立ちます。

レッツは言う頂点Aは、2人の隣人BとCがあり、Bは一つの隣接Dを持っています

白い色の頂点Aから開始し、灰色にし、その隣に移動します。

アルファベット順を選択して、白色で灰色としてマークされている頂点Bにアクセスするとします。

次に、白のDを訪問->灰色のD- >隣人はもういません。したがって、D-> blackとマークされます。

現在、グレーでBにバックトラックし、これ以上nieghborsはありません。したがって、B->黒とマークされます。

再び灰色とするマークC訪問におけるA後戻りC->グレーブラックとしてもはや近隣マークCを

最後に、Aに戻って、頂点Aが黒であるとマークします。これは、白い頂点がなくなり、すべて黒になるためです。


ここで、グレーと黒の区別に何らかの目的があるかどうかわかりません。
user680513

それはあなたが理解しなければならないことです。頂点が黒としてマークされている場合、その頂点に隣接する頂点がないことを意味します。ここでは、隣接する頂点がないため、頂点Dが黒でマークされています。グレーが示唆するように、訪問する隣接がさらにあるため、それらを通過します。
NRK

私はそれはあなたが特定のために知っているだけで、再訪問のノードからあなたを節約できますが、何のバックエッジ(すなわち、最適化)していないと信じて
Setheron

0

DFSでは、エッジをフォワードエッジ、バックエッジ、クロスエッジ、ツリーエッジに分類します。

3色を使用してエッジを分類します。そして、これらの色は、頂点の状態、すなわちv。白を表します:頂点vはまだ発見されていません。

灰色:vはすでに発見されていますが、vから到達可能なすべての頂点はまだ発見されていません。そのため、頂点vはまだスタック内にあります。

黒:vはすでにstack.discoveredからポップアウトされ、終了しています。

DFSを実行する際に、エッジeを介して灰色の頂点に遭遇した場合、それはバックエッジです。エッジeを介して黒い頂点に遭遇した場合、それはクロスエッジ/フォワードエッジです。白い頂点に遭遇した場合、DFSを再帰的に呼び出します。


わかりましたが、ポイントは何ですか?白/灰色/黒は、進む/戻る/クロス/ツリーに関連していると言いましたが、それらが何のためにあるのかは言いません。そのため、質問者が理解していないものが3つだけではなく、7つあります!
デビッドリチャービー

これらのエッジは、グラフのループの識別にバックエッジが使用され、頂点のすべてのペア間に一意のパスが存在するかどうかをテストするためにフォワードエッジが使用されるなど、DFSのさまざまなアプリケーションで使用できます。
ニーラジシン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.