使用BFS进行循环检测

时间:2013-01-24 19:05:11

标签: algorithm graph breadth-first-search

我试图在有向图中检测具有BFS算法的循环。我检测周期的主要想法是:因为BFS只访问每个节点(和边缘)一次,如果我再次遇到已经访问过的节点;它会导致一个循环。但是,我的代码有时会找到循环,有时不会。

我从维基百科修改的伪代码如下:

1  procedure BFS(G,v):
2      create a queue Q
3      enqueue v onto Q
4      mark v
5      while Q is not empty:
6          t <- Q.dequeue()
7          if t is what we are looking for:
8              return t
9          for all edges e in G.adjacentEdges(t) do
12             u <- G.adjacentVertex(t,e)
13             if u is not marked:
14                  mark u
15                  enqueue u onto Q
16             else:
17                  print "Cycle detected!" //since we saw this node before

我错过了什么?

4 个答案:

答案 0 :(得分:4)

您找到的算法可能会在找到周期之前找到目标节点(因此退出)。

对您来说哪个更重要:尽快找到目标或找到周期?如果您根本不关心目标,可以删除算法的那一部分。

答案 1 :(得分:0)

您的实施问题是它假定图表已连接。但实际情况是,您可能会处理具有两个连接部分的图形,因此如果您从v开始,您将永远不会进入另一部分。要解决您的问题,您需要找到一种方法来识别可能未连接的子图。您可以在维基百科上找到一些建议http://en.wikipedia.org/wiki/Topological_sorting#Algorithms,在那里他们谈论

 S ← Set of all nodes with no incoming edges

编辑:

实际上,您可以轻松进行更改,而不是将v入队,将所有节点Dijkstra style排入队列。这样你应该总能找到你的周期。你也从哪里获得t,因为它不是方法签名的一部分?

答案 2 :(得分:0)

即使没有循环,您提供的算法也可能会报告循环的存在。 在第12行,你我们在t附近。 BFS树中t的也位于它的邻接列表中。 So, line 13 might return false even when no cycle exist because a parent of t is marked and is a part of t's adjacency list.

所以,我认为这个算法会报告一个周期,如果它存在,但它也可能报告一个周期,即使没有。

答案 3 :(得分:0)

您的算法将不会总是找到循环。因为,如果节点 v 在任何周期中都不存在,或者无法从节点 v 到达周期,则它将不起作用。我们可以做一些修改。 节点数等于 n 。 从每个节点运行bfs。 伪代码:

1 create a queue Q
2 create a array visited
3 create a array level
4 set answer = infinity
5 for each node 1 to **n**
6      mark the visited equals to **0**.  
7      clear the **Q**
8      enqueue **v** onto Q
9      visited [ v ] = 1
10     while Q is not empty:
11            t <- Q.dequeue()
12            for all edges e in G.adjacentEdges(t) do
13            u <- G.adjacentVertex(t,e)          
14            if u is not visited:
15                 visited [ u ] = 1
16                 level [ u ] = level [ t ] + 1;
17                 enqueue u onto Q
18            else:
19                 answer = min( answer , level [ t ] + level [ u ] + 1 )

算法完成后,您将获得整个图中最小的周期作为答案。