Algorithm BFS循环检测
我试图在有向图中用BFS算法检测循环。我检测循环的主要想法是:由于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
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
: