Algorithm BFS循环检测

Algorithm BFS循环检测,algorithm,graph,breadth-first-search,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.deque

我试图在有向图中用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
1程序BFS(G,v):
2创建一个队列Q
3将v排到Q上
4马克五
5当Q不为空时:

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


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

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


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

实现的问题在于它假设图形是连接的。但现实情况是,你可能要处理一个有两个相连部分的图,因此如果你从
v
开始,你就永远不会进入另一部分。要解决您的问题,您需要找到一种方法来识别可能未连接的子图。你可以在维基百科上找到一些他们谈论的建议

 S ← Set of all nodes with no incoming edges
编辑:


实际上,您可以做一个简单的更改,而不是让所有节点排队。这样,你应该总能找到你的周期。另外,由于它不是方法签名的一部分,您从何处获得
t

实现的问题在于它假定图形是连接的。但现实情况是,你可能要处理一个有两个相连部分的图,因此如果你从
v
开始,你就永远不会进入另一部分。要解决您的问题,您需要找到一种方法来识别可能未连接的子图。你可以在维基百科上找到一些他们谈论的建议

 S ← Set of all nodes with no incoming edges
编辑:


实际上,您可以做一个简单的更改,而不是让所有节点排队。这样,你应该总能找到你的周期。另外,由于它不是方法签名的一部分,您从哪里获得
t

您给出的算法可能会报告循环的存在,即使不存在循环。 在第12行中,我们有u与t相邻。BFS树中t的父级也位于它的邻接列表中。
因此,即使不存在循环,第13行也可能返回false,因为t的父项被标记并且是t的邻接列表的一部分。


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

您给出的算法可能报告一个循环的存在,即使没有循环存在。 在第12行中,我们有u与t相邻。BFS树中t的父级也位于它的邻接列表中。
因此,即使不存在循环,第13行也可能返回false,因为t的父项被标记并且是t的邻接列表的一部分。


因此,我认为如果存在循环,该算法将报告循环,但即使没有循环,它也可能报告循环。

您的算法不会总是找到循环。因为,如果节点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 )
1创建一个队列Q
2创建一个数组
3创建一个数组级别
4设定答案=无穷大
每个节点5个1到**n**
6将访问的值标记为**0**。
7清除**Q**
8排队**v**到Q
9访问量[v]=1
10当Q不为空时:

11 t您的算法不会总是找到循环。因为,如果节点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 )
1创建一个队列Q
2创建一个数组
3创建一个数组级别
4设定答案=无穷大
每个节点5个1到**n**
6将访问的值标记为**0**。
7清除**Q**
8排队**v**到Q
9访问量[v]=1
10当Q不为空时:

11 t当您想要检测周期时,您是否遍历所有节点?由于它不是签名
程序BFS(G,v)的一部分,您从哪里获得
t
当您想要检测周期时,您是否遍历所有节点?由于它不是签名
程序BFS(G,v)的一部分,您从哪里获得
t