web-dev-qa-db-ja.com

グラフで強連結成分を見つける方法は?

私は独学のグラフ理論を試していますが、グラフで [〜#〜] scc [〜#〜] を見つける方法を理解しようとしています。 SO(eg、 12 、、-)に関するいくつかの異なる質問/回答を読みました 45678 )、しかし私はそれを見つけることができません完全なステップバイステップの例で、私は従うことができました。

CORMEN(Introduction to Algorithms) によると、1つの方法は次のとおりです。

  1. DFS(G)を呼び出して、各頂点uの終了時間f [u]を計算します
  2. 移調(G)の計算
  3. DFS(Transpose(G))を呼び出しますが、DFSのメインループで、f [u]の降順で頂点を検討します(ステップ1で計算)。
  4. ステップ3の深さ優先フォレスト内の各ツリーの頂点を個別の強連結成分として出力します

次のグラフを観察してください(質問は ここ から3.4です ここここ のいくつかの解決策を見つけましたが、これを分解しようとしています自分で理解してください。)

enter image description here

ステップ1:DFS(G)を呼び出して、各頂点uの終了時間f [u]を計算します。

頂点Aから始まるDFSの実行:

enter image description here

[Pre-Vist、Post-Visit]としてフォーマットされた赤いテキストに注意してください

ステップ2:Transpose(G)を計算する

enter image description here

ステップ3. DFS(Transpose(G))を呼び出しますが、DFSのメインループで、f [u]の降順で頂点を検討します(ステップ1で計算)

さて、訪問後(終了時間)の値が降順の頂点:

{E、B、A、H、G、I、C、D、F、J}

したがって、このステップでは、G ^ TでDFSを実行しますが、上記のリストの各頂点から開始します。

  • DFS(E):{E}
  • DFS(B):{B}
  • DFS(A):{A}
  • DFS(H):{H、I、G}
  • DFS(G):すでにアクセスされているため、リストから削除します
  • DFS(I):すでにアクセスされているため、リストから削除します
  • DFS(C):{C、J、F、D}
  • DFS(J):すでにアクセスされているため、リストから削除します
  • DFS(F):すでにアクセスされているため、リストから削除します
  • DFS(D):すでにアクセスされているため、リストから削除します

ステップ4:ステップ3の深さ優先フォレスト内の各ツリーの頂点を個別の強連結成分として出力します。

したがって、5つの強連結成分があります:{E}、{B}、{A}、{H、I、G}、{C、J、F、D}

これは私が正しいと信じていることです。しかし、私が見つけた解決策 ここ および ここ は、SCCが{C、J、F、H、I、G、D}および{A、E、B}であると言います。私の間違いはどこにありますか?

14
lucidgold

あなたのステップは正しく、あなたの答えも正しいです、あなたが提供した他の答えを調べることによって、それらが異なるアルゴリズムを使用したことがわかります:最初にG転置でDFSを実行し、次にGで無向コンポーネントアルゴリズムを実行して頂点を減少させます前のステップからの投稿番号の順序。

問題は、Gではなく転置されたGでこの最後のステップを実行したため、誤った回答が得られたことです。 Dasguptaを98ページ以降で読むと、Dasguptaが使用しようとした(試した)アルゴリズムの詳細な説明が表示されます。

0
hbejgel

あなたの答えは正しいです。 CLRSによると、「有向グラフG =(V、E)の強く接続されたコンポーネントは、頂点Cの最大セットであり、頂点uとvのすべてのペアに対して、u〜> vとv〜>の両方があります。 u、つまり頂点vとuは互いに到達可能です。」

{C、J、F、H、I、G、D}が正しいと仮定した場合、(他の多くの誤謬の中で)DからGに到達する方法はなく、他のセットと同じように、 AからEに到達します。

0
kaustubh