【问题标题】:Cycle detection with BFS使用 BFS 进行循环检测
【发布时间】:2013-01-24 19:05:10
【问题描述】:

我正在尝试使用 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

我错过了什么?

【问题讨论】:

  • 要检测循环的时候是否遍历所有节点?
  • 你从哪里得到t,因为它不是签名procedure BFS(G,v):的一部分

标签: algorithm graph breadth-first-search


【解决方案1】:

您给出的算法可能会在找到循环之前找到目标节点(并因此退出)。

哪个对您更重要:尽快找到目标还是找到循环?如果您根本不关心目标,则可以删除算法的那部分。

【讨论】:

    【解决方案2】:

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

     S ← Set of all nodes with no incoming edges
    

    编辑:

    实际上,您可以做的一个简单更改是,将所有节点排入队列 @9​​87654322@,而不是将 v 排入队列。这样你应该总能找到你的周期。还有你从哪里得到t,因为它不是方法签名的一部分?

    【讨论】:

      【解决方案3】:

      即使不存在循环,您给出的算法也可能会报告存在循环。 在第 12 行,你我们有 u 与 t 相邻。 BFS 树中 t 的 parent 也位于它的邻接表中。 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.

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

      【讨论】:

        【解决方案4】:

        您的算法不会总能找到循环。因为,如果节点 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 )
        

        完成算法后,您将得到整个图中的最小循环作为答案。

        【讨论】:

          猜你喜欢
          • 2017-06-15
          • 1970-01-01
          • 1970-01-01
          • 2012-01-11
          • 1970-01-01
          • 2018-10-21
          • 2011-01-25
          • 2010-12-16
          • 1970-01-01
          相关资源
          最近更新 更多