用DFS检测有向图中的循环

Detecting a cycle in a directed graph using DFS?

本文关键字:循环 有向图 DFS 检测      更新时间:2023-10-16

所以,我试图在有向图中使用DFS找到一个循环。现在,我知道如果一个图的拓扑排序是不可能的,那么这个图包含一个循环。我做了如下的拓扑排序算法。我不确定我应该在哪里修改这个代码,以便return truefalse,并检查我的图是否包含一个循环。下面是我使用的算法:

DFS-Loop (Graph G)
1. Mark all vertices as unexplored.
2. Set label = n // number of vertices
3. For each vertex V (belonging to) G
   -- If V not yet explored,
   -- DFS (G,V)
4. Set f(V) = current_label // here, f(V) is basically the position of V in the ordering
5. current_label-- 
Where DFS(G,V) will be something like: 
1. Mark V as explored.
2. For every vertex K belonging to Adj.(V)
   -- If K is not explored, 
   -- Call DFS(G,K)

我应该在哪里添加这个检查是否包含循环?

谢谢!

在有向图中查找环的最简单方法如下:

使用三个顶点状态:"未探索","正在探索"answers"完全探索"。当你输入一个新顶点时,将其设置为"正在探索",当你完成一个顶点时,将其设置为"完全探索"。现在,当你遍历某个顶点的相邻点时,如果你到达一个"正在被探索"的顶点,那么这就是一个循环。

DFS(G,V):
1. Mark V as "being explored"
2. For every vertex K belonging to Adj.(V)
   -- If K is not explored, 
      -- Call DFS(G,K)
   -- else if K is "being explored" (not "fully explored")
      -- then there is a cycle
3. Mark V as "fully explored" 

你可以从你找到的"正在探索的"顶点回溯找到循环。

另一种方法是允许基于dfs的拓扑排序运行并创建一些顶点排序。现在遍历所有边并检查它们是否正确定向。

如果所有边都正确定向,则不存在循环,否则至少存在一个。

对于无向图,请遵循以下步骤-

1)代替布尔访问数组,使其为int类型,所有索引初始化为-1。

这里1 = 不是探讨, 0 = 正在探索, 1 = 充分探讨

2)初始化全局布尔变量标志为false。

这里true = 包含循环,false = 不包含循环

3)现在编写DFS如下(以下是c++代码)-

void dfs(int s)
{
    visited[s] = 0;
    for(int i = 0; i < adj[s].size(); i++)
    {
        if(visited[ adj[s][i] ] == -1)
        {
            dfs(adj[s][i]);
        }
        else if(visited[adj[s][i]] == 1)
        {
            flag = true;
            return;
        }
    }
    visited[s] = 1;
}

我建议阅读"算法—介绍"(Cormen et. al)中的相应章节。

基本上你需要检测,当你重访一个未完成的顶点时:

不是将顶点V标记为探索/未探索,而是添加一个额外的标签状态"currently_explore"。每个顶点在开始时都被标记为未探索(就像现在一样)。但是它在DFS的第一步被标记为"currently_explore"(而不是explore),并在DFS的for-loop 2之后标记为explore。

在DFS中递归调用之前,检查状态。如果它是未探索的,只需递归调用(就像当前一样)。如果它是currently_explore,那么您已经检测到一个循环!(如果它是"探索"的,则称为前边缘,此处不再讨论)。

注意,这可以集成到拓扑排序算法中