繁体   English   中英

在有向图中检测周期

[英]Detecting a cycle in a directed graph

在这里阅读了关于在有向图中找到循环的讨论。 现在,OP声称我们需要验证件事:

  1. uv有一个后沿
  2. v在递归堆栈中

为什么我们需要第二次测试? 您能举个例子证明它的必要性吗?

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

简单的图形反例:

反

数字是遍历顺序。 我们的后缘为4到3,但没有任何循环。

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

无向图中,后边缘是从当前顶点到已访问的顶点的边缘。 (如您提到的链接中的OP)。
在有向图中,后边缘的定义不同。 有向图的后边缘是从当前顶点到GREY顶点的边缘(此顶点的DFS已开始但尚未完成),这意味着它仍在递归堆栈中。

因此,如果按照有向图中的方式定义后沿,则可以,它足以检测周期。
但是,如果您将后缘的定义定义为无向图中,那么您还需要确保v在递归堆栈中以检测循环。

这个这个以获取更多信息和示例。

例:
考虑DFS访问顺序为A -> B -> C
在此示例中,边<A,C>是带下划线的图中的后边(因为C已被访问)。
但这不是该有向图的后边缘-C已被访问但不在递归堆栈中,这意味着它不是循环。 在此处输入图片说明

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

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

根据处理顺序,可以将d->c视为交叉边缘,因此需要步骤2来检测循环。 不幸的是,后边缘和交叉边缘经常混合在一起,从而引起混乱。 这是指向两者之间差异的另一描述的链接,即深度优先搜索

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM