How do I check if a directed graph is acyclic?

后端 未结 11 1747
野的像风
野的像风 2020-11-30 19:16

How do I check if a directed graph is acyclic? And how is the algorithm called? I would appreciate a reference.

相关标签:
11条回答
  • 2020-11-30 19:37

    There should not be any back edge while doing DFS.Keep track of already visited nodes while doing DFS,if you encounter a edge between current node and existing node,then graph has cycle.

    0 讨论(0)
  • 2020-11-30 19:37

    You can use inversion of finding cycle from my answer here https://stackoverflow.com/a/60196714/1763149

    def is_acyclic(graph):
        return not has_cycle(graph)
    
    0 讨论(0)
  • 2020-11-30 19:40

    The solution given by ShuggyCoUk is incomplete because it might not check all nodes.

    
    def isDAG(nodes V):
        while there is an unvisited node v in V:
            bool cycleFound = dfs(v)
            if cyclefound:
                return false
        return true
    

    This has timecomplexity O(n+m) or O(n^2)

    0 讨论(0)
  • 2020-11-30 19:40

    here is a swift code to find if a graph has cycles :

    func isCyclic(G : Dictionary<Int,Array<Int>>,root : Int , var visited : Array<Bool>,var breadCrumb : Array<Bool>)-> Bool
    {
    
        if(breadCrumb[root] == true)
        {
            return true;
        }
    
        if(visited[root] == true)
        {
            return false;
        }
    
        visited[root] = true;
    
        breadCrumb[root] = true;
    
        if(G[root] != nil)
        {
            for child : Int in G[root]!
            {
                if(isCyclic(G,root : child,visited : visited,breadCrumb : breadCrumb))
                {
                    return true;
                }
            }
        }
    
        breadCrumb[root] = false;
        return false;
    }
    
    
    let G = [0:[1,2,3],1:[4,5,6],2:[3,7,6],3:[5,7,8],5:[2]];
    
    var visited = [false,false,false,false,false,false,false,false,false];
    var breadCrumb = [false,false,false,false,false,false,false,false,false];
    
    
    
    
    var isthereCycles = isCyclic(G,root : 0, visited : visited, breadCrumb : breadCrumb)
    

    The idea is like this : a normal dfs algorithm with an array to keep track of visited nodes , and an additional array which serves as a marker for the nodes that led to the current node,so that when ever we execute a dfs for a node we set its corresponding item in the marker array as true ,so that when ever an already visited node encountered we check if its corresponding item in the marker array is true , if its true then its one of the nodes that let to itself (hence a cycle) , and the trick is whenever a dfs of a node returns we set its corresponding marker back to false , so that if we visited it again from another route we don't get fooled .

    0 讨论(0)
  • 2020-11-30 19:47

    Doing a simple depth-first-search is not good enough to find a cycle. It is possible to visit a node multiple times in a DFS without a cycle existing. Depending on where you start, you also might not visit the entire graph.

    You can check for cycles in a connected component of a graph as follows. Find a node which has only outgoing edges. If there is no such node, then there is a cycle. Start a DFS at that node. When traversing each edge, check whether the edge points back to a node already on your stack. This indicates the existence of a cycle. If you find no such edge, there are no cycles in that connected component.

    As Rutger Prins points out, if your graph is not connected, you need to repeat the search on each connected component.

    As a reference, Tarjan's strongly connected component algorithm is closely related. It will also help you find the cycles, not just report whether they exist.

    0 讨论(0)
提交回复
热议问题