检测有向图中的循环

时间:2016-09-11 11:29:36

标签: algorithm graph computer-science

我读了一篇关于在有向图中找到一个循环的讨论here。现在,OP声称我们需要验证两个的东西:

  1. uv
  2. 有一个后沿
  3. v在递归堆栈中
  4. 为什么我们需要第二次测试?你能举例说明它的必要性吗?

3 个答案:

答案 0 :(得分:1)

只有我们已经访问v的事实是不够的。它允许我们从u转到v,但不能从v转到u

简单的图形反例:

Counterexample

数字是遍历顺序。我们有4到3的后沿,但我们没有任何周期。

答案 1 :(得分:1)

好吧,你可能会对有向图中后沿的定义和无向图中的后沿感到困惑。是的,他们是不同的。

无向图中,后边是从当前顶点到已经访问过的顶点的边。 (作为你提到的链接的OP) 在有向图中,后边缘的定义是不同的。有向图中的后沿是从当前顶点到GRAY顶点的边(该顶点的DFS已经开始但尚未完成),这意味着它仍然在递归堆栈中。

因此,如果您在有向图中采用后边缘的定义,那么是的,它足以检测周期。
但是如果你在后向边缘中定义后边缘,那么你还需要确保v在递归堆栈中以便检测一个循环。

有关详细信息和示例,请参阅thisthis

示例:
将DFS访问顺序视为A -> B -> C 在此示例中,边<A,C>是已显示图中的后边缘(因为C已被访问过)。
但它不是这个有向图中的后沿 - 已经访问过C但不在递归堆栈中,这意味着它不是一个循环。 enter image description here

答案 2 :(得分:1)

当它是交叉边而不是后边缘时,需要进行第二次测试。交叉边缘指的是从一个顶点到已经访问过的一个边缘的边缘,而与位置无关。 后边缘指的是指向起始顶点的祖先的边,一个仍然在递归堆栈中的边。就问题的提问方式而言,OP将后边缘称为指向另一个已访问边缘的边缘,但更准确的解释是交叉边缘。知道它是一个后沿是足够的,因为它意味着第二步。当第一个是交叉边缘时需要这些步骤,因为第二个证明交叉边缘是后边缘。在有向图中,交叉边缘并不总是意味着发生了循环。这是一个例子:

vertices a,b,c,d
a->b
a->c
b->d
d->c

根据处理此顺序,d->c可视为交叉边缘,因此检测循环需要步骤2。不幸的是,后边缘和交叉边缘经常混淆,造成这样的混乱。下面是另一个关于两者之间差异的描述的链接,Depth-First Search