@@ -231,14 +231,14 @@ impl<N: Debug, E: Debug> Graph<N, E> {
231231
232232 // # Iterating over nodes, edges
233233
234- pub fn all_nodes_enumerated ( & self ) -> Nodes < N > {
235- Nodes {
234+ pub fn enumerated_nodes ( & self ) -> EnumeratedNodes < N > {
235+ EnumeratedNodes {
236236 iter : self . nodes . iter ( ) . enumerate ( )
237237 }
238238 }
239239
240- pub fn all_edges_enumerated ( & self ) -> Edges < E > {
241- Edges {
240+ pub fn enumerated_edges ( & self ) -> EnumeratedEdges < E > {
241+ EnumeratedEdges {
242242 iter : self . edges . iter ( ) . enumerate ( )
243243 }
244244 }
@@ -247,14 +247,14 @@ impl<N: Debug, E: Debug> Graph<N, E> {
247247 where F : FnMut ( NodeIndex , & ' a Node < N > ) -> bool
248248 {
249249 //! Iterates over all edges defined in the graph.
250- self . all_nodes_enumerated ( ) . all ( |( node_idx, node) | f ( node_idx, node) )
250+ self . enumerated_nodes ( ) . all ( |( node_idx, node) | f ( node_idx, node) )
251251 }
252252
253253 pub fn each_edge < ' a , F > ( & ' a self , mut f : F ) -> bool
254254 where F : FnMut ( EdgeIndex , & ' a Edge < E > ) -> bool
255255 {
256256 //! Iterates over all edges defined in the graph
257- self . all_edges_enumerated ( ) . all ( |( edge_idx, edge) | f ( edge_idx, edge) )
257+ self . enumerated_edges ( ) . all ( |( edge_idx, edge) | f ( edge_idx, edge) )
258258 }
259259
260260 pub fn outgoing_edges ( & self , source : NodeIndex ) -> AdjacentEdges < N , E > {
@@ -295,7 +295,7 @@ impl<N: Debug, E: Debug> Graph<N, E> {
295295 while changed {
296296 changed = false ;
297297 iteration += 1 ;
298- for ( edge_index, edge) in self . all_edges_enumerated ( ) {
298+ for ( edge_index, edge) in self . enumerated_edges ( ) {
299299 changed |= op ( iteration, edge_index, edge) ;
300300 }
301301 }
@@ -307,31 +307,60 @@ impl<N: Debug, E: Debug> Graph<N, E> {
307307 -> DepthFirstTraversal < ' a , N , E > {
308308 DepthFirstTraversal :: with_start_node ( self , start, direction)
309309 }
310+
311+ /// Whether or not a node can be reached from itself.
312+ pub fn is_node_cyclic ( & self , starting_node_index : NodeIndex ) -> bool {
313+ // This is similar to depth traversal below, but we
314+ // can't use that, because depth traversal doesn't show
315+ // the starting node a second time.
316+ let mut visited = BitVector :: new ( self . len_nodes ( ) ) ;
317+ let mut stack = vec ! [ starting_node_index] ;
318+
319+ while let Some ( current_node_index) = stack. pop ( ) {
320+ visited. insert ( current_node_index. 0 ) ;
321+
322+ // Directionality doesn't change the answer,
323+ // so just use outgoing edges.
324+ for ( _, edge) in self . outgoing_edges ( current_node_index) {
325+ let target_node_index = edge. target ( ) ;
326+
327+ if target_node_index == starting_node_index {
328+ return true ;
329+ }
330+
331+ if !visited. contains ( target_node_index. 0 ) {
332+ stack. push ( target_node_index) ;
333+ }
334+ }
335+ }
336+
337+ false
338+ }
310339}
311340
312341// # Iterators
313342
314- pub struct Nodes < ' g , N >
343+ pub struct EnumeratedNodes < ' g , N >
315344 where N : ' g ,
316345{
317346 iter : :: std:: iter:: Enumerate < :: std:: slice:: Iter < ' g , Node < N > > >
318347}
319348
320- impl < ' g , N : Debug > Iterator for Nodes < ' g , N > {
349+ impl < ' g , N : Debug > Iterator for EnumeratedNodes < ' g , N > {
321350 type Item = ( NodeIndex , & ' g Node < N > ) ;
322351
323352 fn next ( & mut self ) -> Option < ( NodeIndex , & ' g Node < N > ) > {
324353 self . iter . next ( ) . map ( |( idx, n) | ( NodeIndex ( idx) , n) )
325354 }
326355}
327356
328- pub struct Edges < ' g , E >
357+ pub struct EnumeratedEdges < ' g , E >
329358 where E : ' g ,
330359{
331360 iter : :: std:: iter:: Enumerate < :: std:: slice:: Iter < ' g , Edge < E > > >
332361}
333362
334- impl < ' g , E : Debug > Iterator for Edges < ' g , E > {
363+ impl < ' g , E : Debug > Iterator for EnumeratedEdges < ' g , E > {
335364 type Item = ( EdgeIndex , & ' g Edge < E > ) ;
336365
337366 fn next ( & mut self ) -> Option < ( EdgeIndex , & ' g Edge < E > ) > {
0 commit comments