fn has_cycle<Dir, G>(&mut self, graph: &'a G, src_virt_id: usize, parent_virt_id: usize) -> bool
    where
        E: Edge<W>,
        Dir: EdgeDir,
        G: provide::Neighbors + Vertices + Graph<W, E, Dir> + Edges<W, E>,
    {
        self.is_visited[src_virt_id] = true;

        let src_real_id = self.id_map.real_id_of(src_virt_id);

        for (dst_real_id, edge) in graph.edges_from(src_real_id).unwrap() {
            let dst_virt_id = self.id_map.virt_id_of(dst_real_id);

            // If child is not already visited, try to find a cycle that contains (src_id, dst_id) edge.
            if !self.is_visited[dst_virt_id] {
                self.edge_stack.push((src_real_id, dst_real_id, edge));
                if self.has_cycle(graph, dst_virt_id, src_virt_id) {
                    return true;
                } else {
                    // If failed to find any cycle that contains this edge, remove it from stack.
                    self.edge_stack.pop();
                }
            } else if !self.is_finished[dst_virt_id]
                && (Dir::is_directed() || dst_virt_id != parent_virt_id)
            {
                // If child is visited but not finished, means we visited it once before and got back to it using a different route.
                // But for this route to be cycle, the graph either:
                // * Must be directed to prevent detecting: v1 --- v2 as cycle.
                // * Is undirected which child can not be parent of the current vertex. Again to prevent detecting cycle in scenario: v1 --- v2.
                self.edge_stack.push((src_real_id, dst_real_id, edge));
                return true;
            }
        }

        self.is_finished[src_virt_id] = true;

        false
    }
// Recursively searches for cycles in graph
//
// # Arguments
// * `graph`: Graph to search for cycles in it.
// * `src_virt_id`: Virtual id of the current vertex.
// * `parent_virt_id`: Virtual id of the parent of the current vertex.
//
// # Returns
// * `true`: If graph has cycle.
// * `false`: Otherwise.
Recursively searches for cycles in graph
Recursively searches for cycles in graph
fn has_cycle<Dir, G>(&mut self, graph: &'a G, src_virt_id: usize, parent_virt_id: usize) -> bool
    where
        E: Edge<W>,
        Dir: EdgeDir,
        G: provide::Neighbors + Vertices + Graph<W, E, Dir> + Edges<W, E>,
    {
        self.is_visited[src_virt_id] = true;
        let src_real_id = self.id_map.real_id_of(src_virt_id);
        for (dst_real_id, edge) in graph.edges_from(src_real_id).unwrap() {
            let dst_virt_id = self.id_map.virt_id_of(dst_real_id);
            // If child is not already visited, try to find a cycle that contains (src_id, dst_id) edge.
            if !self.is_visited[dst_virt_id] {
                self.edge_stack.push((src_real_id, dst_real_id, edge));
                if self.has_cycle(graph, dst_virt_id, src_virt_id) {
                    return true;
                } else {
                    // If failed to find any cycle that contains this edge, remove it from stack.
                    self.edge_stack.pop();
                }
            } else if !self.is_finished[dst_virt_id]
                && (Dir::is_directed() || dst_virt_id != parent_virt_id)
            {
                // If child is visited but not finished, means we visited it once before and got back to it using a different route.
                // But for this route to be cycle, the graph either:
                // * Must be directed to prevent detecting: v1 --- v2 as cycle.
                // * Is undirected which child can not be parent of the current vertex. Again to prevent detecting cycle in scenario: v1 --- v2.
                self.edge_stack.push((src_real_id, dst_real_id, edge));
                return true;
            }
        }
        self.is_finished[src_virt_id] = true;
        false
    }
fn has_cycle < Dir , G > ( & mut self , graph : & ' a G , src_virt_id : usize , parent_virt_id : usize ) -> bool where E : Edge < W > , Dir : EdgeDir , G : provide :: Neighbors + Vertices + Graph < W , E , Dir > + Edges < W , E > , { self . is_visited [ src_virt_id ] = true ; let src_real_id = self . id_map . real_id_of ( src_virt_id ) ; for ( dst_real_id , edge ) in graph . edges_from ( src_real_id ) . unwrap ( ) { let dst_virt_id = self . id_map . virt_id_of ( dst_real_id ) ; // If child is not already visited, try to find a cycle that contains (src_id, dst_id) edge. if ! self . is_visited [ dst_virt_id ] { self . edge_stack . push ( ( src_real_id , dst_real_id , edge ) ) ; if self . has_cycle ( graph , dst_virt_id , src_virt_id ) { return true ; } else { // If failed to find any cycle that contains this edge, remove it from stack. self . edge_stack . pop ( ) ; } } else if ! self . is_finished [ dst_virt_id ] && ( Dir :: is_directed ( ) || dst_virt_id != parent_virt_id ) { // If child is visited but not finished, means we visited it once before and got back to it using a different route. // But for this route to be cycle, the graph either: // * Must be directed to prevent detecting: v1 --- v2 as cycle. // * Is undirected which child can not be parent of the current vertex. Again to prevent detecting cycle in scenario: v1 --- v2. self . edge_stack . push ( ( src_real_id , dst_real_id , edge ) ) ; return true ; } } self . is_finished [ src_virt_id ] = true ; false }
Recursively searches for cycles in graph
Recursively searches for cycles in graph
&mut self
graph
&'a G
src_virt_id
usize
parent_virt_id
usize
`true`: If graph has cycle.
`false`: Otherwise.
` true ` : If graph has cycle . ` false ` : Otherwise .
&mut self
graph
&'a G
src_virt_id
usize
parent_virt_id
usize