このSO 投稿に出くわしました。有向グラフで DFS を使用したサイクル検出は、バックトラッキングのために高速であることが示唆されています。ここで私はそのリンクから引用します:
深さ優先検索は、幅優先検索よりも早くバックトラックできるため、メモリ効率が高くなります。コール スタックを使用すると実装も簡単になりますが、これはスタックをオーバーフローしない最長パスに依存します。
また、グラフが方向付けされている場合は、ノードにアクセスしたかどうかだけでなく、どのようにしてそこに到達したかを覚えておく必要があります。そうでなければ、サイクルを見つけたと思うかもしれませんが、実際には 2 つの別個のパス A->B しかありませんが、それはパス B->A があるという意味ではありません。深さ優先検索を使用すると、下降するときにノードを訪問済みとしてマークし、バックトラックするときにそれらのマークを解除できます。
バックトラックが不可欠な理由
与えられた例で何を意味するのか、誰かが例のグラフで説明できますかA->B
?
最後に、DFS
バックトラッキングを使用しない有向グラフでのサイクル検出のコードがありますが、それでもサイクルで検出されO(E+V)
ます。
public boolean isCyclicDirected(Vertex v){
if (v.isVisited) {
return true;
}
v.setVisited(true);
Iterator<Edge> e = v.adj.iterator();
while (e.hasNext()) {
Vertex t = e.next().target;
// quick test:
if (t.isVisited) {
return true;
}
// elaborate, recursive test:
if (isCyclicDirected(t)) {
return true;
}
}
// none of our adjacent vertices flag as cyclic
v.setVisited(false);
return false;
}