1 use super::{GraphRef, IntoNodeIdentifiers, Reversed};
2 use super::{IntoNeighbors, IntoNeighborsDirected, VisitMap, Visitable};
3 use crate::Incoming;
4 use std::collections::VecDeque;
5 
6 /// Visit nodes of a graph in a depth-first-search (DFS) emitting nodes in
7 /// preorder (when they are first discovered).
8 ///
9 /// The traversal starts at a given node and only traverses nodes reachable
10 /// from it.
11 ///
12 /// `Dfs` is not recursive.
13 ///
14 /// `Dfs` does not itself borrow the graph, and because of this you can run
15 /// a traversal over a graph while still retaining mutable access to it, if you
16 /// use it like the following example:
17 ///
18 /// ```
19 /// use petgraph::Graph;
20 /// use petgraph::visit::Dfs;
21 ///
22 /// let mut graph = Graph::<_,()>::new();
23 /// let a = graph.add_node(0);
24 ///
25 /// let mut dfs = Dfs::new(&graph, a);
26 /// while let Some(nx) = dfs.next(&graph) {
27 ///     // we can access `graph` mutably here still
28 ///     graph[nx] += 1;
29 /// }
30 ///
31 /// assert_eq!(graph[a], 1);
32 /// ```
33 ///
34 /// **Note:** The algorithm may not behave correctly if nodes are removed
35 /// during iteration. It may not necessarily visit added nodes or edges.
36 #[derive(Clone, Debug)]
37 pub struct Dfs<N, VM> {
38     /// The stack of nodes to visit
39     pub stack: Vec<N>,
40     /// The map of discovered nodes
41     pub discovered: VM,
42 }
43 
44 impl<N, VM> Default for Dfs<N, VM>
45 where
46     VM: Default,
47 {
default() -> Self48     fn default() -> Self {
49         Dfs {
50             stack: Vec::new(),
51             discovered: VM::default(),
52         }
53     }
54 }
55 
56 impl<N, VM> Dfs<N, VM>
57 where
58     N: Copy + PartialEq,
59     VM: VisitMap<N>,
60 {
61     /// Create a new **Dfs**, using the graph's visitor map, and put **start**
62     /// in the stack of nodes to visit.
new<G>(graph: G, start: N) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,63     pub fn new<G>(graph: G, start: N) -> Self
64     where
65         G: GraphRef + Visitable<NodeId = N, Map = VM>,
66     {
67         let mut dfs = Dfs::empty(graph);
68         dfs.move_to(start);
69         dfs
70     }
71 
72     /// Create a `Dfs` from a vector and a visit map
from_parts(stack: Vec<N>, discovered: VM) -> Self73     pub fn from_parts(stack: Vec<N>, discovered: VM) -> Self {
74         Dfs { stack, discovered }
75     }
76 
77     /// Clear the visit state
reset<G>(&mut self, graph: G) where G: GraphRef + Visitable<NodeId = N, Map = VM>,78     pub fn reset<G>(&mut self, graph: G)
79     where
80         G: GraphRef + Visitable<NodeId = N, Map = VM>,
81     {
82         graph.reset_map(&mut self.discovered);
83         self.stack.clear();
84     }
85 
86     /// Create a new **Dfs** using the graph's visitor map, and no stack.
empty<G>(graph: G) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,87     pub fn empty<G>(graph: G) -> Self
88     where
89         G: GraphRef + Visitable<NodeId = N, Map = VM>,
90     {
91         Dfs {
92             stack: Vec::new(),
93             discovered: graph.visit_map(),
94         }
95     }
96 
97     /// Keep the discovered map, but clear the visit stack and restart
98     /// the dfs from a particular node.
move_to(&mut self, start: N)99     pub fn move_to(&mut self, start: N) {
100         self.stack.clear();
101         self.stack.push(start);
102     }
103 
104     /// Return the next node in the dfs, or **None** if the traversal is done.
next<G>(&mut self, graph: G) -> Option<N> where G: IntoNeighbors<NodeId = N>,105     pub fn next<G>(&mut self, graph: G) -> Option<N>
106     where
107         G: IntoNeighbors<NodeId = N>,
108     {
109         while let Some(node) = self.stack.pop() {
110             if self.discovered.visit(node) {
111                 for succ in graph.neighbors(node) {
112                     if !self.discovered.is_visited(&succ) {
113                         self.stack.push(succ);
114                     }
115                 }
116                 return Some(node);
117             }
118         }
119         None
120     }
121 }
122 
123 /// Visit nodes in a depth-first-search (DFS) emitting nodes in postorder
124 /// (each node after all its descendants have been emitted).
125 ///
126 /// `DfsPostOrder` is not recursive.
127 ///
128 /// The traversal starts at a given node and only traverses nodes reachable
129 /// from it.
130 #[derive(Clone, Debug)]
131 pub struct DfsPostOrder<N, VM> {
132     /// The stack of nodes to visit
133     pub stack: Vec<N>,
134     /// The map of discovered nodes
135     pub discovered: VM,
136     /// The map of finished nodes
137     pub finished: VM,
138 }
139 
140 impl<N, VM> Default for DfsPostOrder<N, VM>
141 where
142     VM: Default,
143 {
default() -> Self144     fn default() -> Self {
145         DfsPostOrder {
146             stack: Vec::new(),
147             discovered: VM::default(),
148             finished: VM::default(),
149         }
150     }
151 }
152 
153 impl<N, VM> DfsPostOrder<N, VM>
154 where
155     N: Copy + PartialEq,
156     VM: VisitMap<N>,
157 {
158     /// Create a new `DfsPostOrder` using the graph's visitor map, and put
159     /// `start` in the stack of nodes to visit.
new<G>(graph: G, start: N) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,160     pub fn new<G>(graph: G, start: N) -> Self
161     where
162         G: GraphRef + Visitable<NodeId = N, Map = VM>,
163     {
164         let mut dfs = Self::empty(graph);
165         dfs.move_to(start);
166         dfs
167     }
168 
169     /// Create a new `DfsPostOrder` using the graph's visitor map, and no stack.
empty<G>(graph: G) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,170     pub fn empty<G>(graph: G) -> Self
171     where
172         G: GraphRef + Visitable<NodeId = N, Map = VM>,
173     {
174         DfsPostOrder {
175             stack: Vec::new(),
176             discovered: graph.visit_map(),
177             finished: graph.visit_map(),
178         }
179     }
180 
181     /// Clear the visit state
reset<G>(&mut self, graph: G) where G: GraphRef + Visitable<NodeId = N, Map = VM>,182     pub fn reset<G>(&mut self, graph: G)
183     where
184         G: GraphRef + Visitable<NodeId = N, Map = VM>,
185     {
186         graph.reset_map(&mut self.discovered);
187         graph.reset_map(&mut self.finished);
188         self.stack.clear();
189     }
190 
191     /// Keep the discovered and finished map, but clear the visit stack and restart
192     /// the dfs from a particular node.
move_to(&mut self, start: N)193     pub fn move_to(&mut self, start: N) {
194         self.stack.clear();
195         self.stack.push(start);
196     }
197 
198     /// Return the next node in the traversal, or `None` if the traversal is done.
next<G>(&mut self, graph: G) -> Option<N> where G: IntoNeighbors<NodeId = N>,199     pub fn next<G>(&mut self, graph: G) -> Option<N>
200     where
201         G: IntoNeighbors<NodeId = N>,
202     {
203         while let Some(&nx) = self.stack.last() {
204             if self.discovered.visit(nx) {
205                 // First time visiting `nx`: Push neighbors, don't pop `nx`
206                 for succ in graph.neighbors(nx) {
207                     if !self.discovered.is_visited(&succ) {
208                         self.stack.push(succ);
209                     }
210                 }
211             } else {
212                 self.stack.pop();
213                 if self.finished.visit(nx) {
214                     // Second time: All reachable nodes must have been finished
215                     return Some(nx);
216                 }
217             }
218         }
219         None
220     }
221 }
222 
223 /// A breadth first search (BFS) of a graph.
224 ///
225 /// The traversal starts at a given node and only traverses nodes reachable
226 /// from it.
227 ///
228 /// `Bfs` is not recursive.
229 ///
230 /// `Bfs` does not itself borrow the graph, and because of this you can run
231 /// a traversal over a graph while still retaining mutable access to it, if you
232 /// use it like the following example:
233 ///
234 /// ```
235 /// use petgraph::Graph;
236 /// use petgraph::visit::Bfs;
237 ///
238 /// let mut graph = Graph::<_,()>::new();
239 /// let a = graph.add_node(0);
240 ///
241 /// let mut bfs = Bfs::new(&graph, a);
242 /// while let Some(nx) = bfs.next(&graph) {
243 ///     // we can access `graph` mutably here still
244 ///     graph[nx] += 1;
245 /// }
246 ///
247 /// assert_eq!(graph[a], 1);
248 /// ```
249 ///
250 /// **Note:** The algorithm may not behave correctly if nodes are removed
251 /// during iteration. It may not necessarily visit added nodes or edges.
252 #[derive(Clone)]
253 pub struct Bfs<N, VM> {
254     /// The queue of nodes to visit
255     pub stack: VecDeque<N>,
256     /// The map of discovered nodes
257     pub discovered: VM,
258 }
259 
260 impl<N, VM> Default for Bfs<N, VM>
261 where
262     VM: Default,
263 {
default() -> Self264     fn default() -> Self {
265         Bfs {
266             stack: VecDeque::new(),
267             discovered: VM::default(),
268         }
269     }
270 }
271 
272 impl<N, VM> Bfs<N, VM>
273 where
274     N: Copy + PartialEq,
275     VM: VisitMap<N>,
276 {
277     /// Create a new **Bfs**, using the graph's visitor map, and put **start**
278     /// in the stack of nodes to visit.
new<G>(graph: G, start: N) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,279     pub fn new<G>(graph: G, start: N) -> Self
280     where
281         G: GraphRef + Visitable<NodeId = N, Map = VM>,
282     {
283         let mut discovered = graph.visit_map();
284         discovered.visit(start);
285         let mut stack = VecDeque::new();
286         stack.push_front(start);
287         Bfs { stack, discovered }
288     }
289 
290     /// Return the next node in the bfs, or **None** if the traversal is done.
next<G>(&mut self, graph: G) -> Option<N> where G: IntoNeighbors<NodeId = N>,291     pub fn next<G>(&mut self, graph: G) -> Option<N>
292     where
293         G: IntoNeighbors<NodeId = N>,
294     {
295         if let Some(node) = self.stack.pop_front() {
296             for succ in graph.neighbors(node) {
297                 if self.discovered.visit(succ) {
298                     self.stack.push_back(succ);
299                 }
300             }
301 
302             return Some(node);
303         }
304         None
305     }
306 }
307 
308 /// A topological order traversal for a graph.
309 ///
310 /// **Note** that `Topo` only visits nodes that are not part of cycles,
311 /// i.e. nodes in a true DAG. Use other visitors like `DfsPostOrder` or
312 /// algorithms like kosaraju_scc to handle graphs with possible cycles.
313 #[derive(Clone)]
314 pub struct Topo<N, VM> {
315     tovisit: Vec<N>,
316     ordered: VM,
317 }
318 
319 impl<N, VM> Default for Topo<N, VM>
320 where
321     VM: Default,
322 {
default() -> Self323     fn default() -> Self {
324         Topo {
325             tovisit: Vec::new(),
326             ordered: VM::default(),
327         }
328     }
329 }
330 
331 impl<N, VM> Topo<N, VM>
332 where
333     N: Copy + PartialEq,
334     VM: VisitMap<N>,
335 {
336     /// Create a new `Topo`, using the graph's visitor map, and put all
337     /// initial nodes in the to visit list.
new<G>(graph: G) -> Self where G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,338     pub fn new<G>(graph: G) -> Self
339     where
340         G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
341     {
342         let mut topo = Self::empty(graph);
343         topo.extend_with_initials(graph);
344         topo
345     }
346 
347     /// Create a new `Topo` with initial nodes.
348     ///
349     /// Nodes with incoming edges are ignored.
with_initials<G, I>(graph: G, initials: I) -> Self where G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>, I: IntoIterator<Item = N>,350     pub fn with_initials<G, I>(graph: G, initials: I) -> Self
351     where
352         G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
353         I: IntoIterator<Item = N>,
354     {
355         Topo {
356             tovisit: initials
357                 .into_iter()
358                 .filter(|&n| graph.neighbors_directed(n, Incoming).next().is_none())
359                 .collect(),
360             ordered: graph.visit_map(),
361         }
362     }
363 
extend_with_initials<G>(&mut self, g: G) where G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,364     fn extend_with_initials<G>(&mut self, g: G)
365     where
366         G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,
367     {
368         // find all initial nodes (nodes without incoming edges)
369         self.tovisit.extend(
370             g.node_identifiers()
371                 .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()),
372         );
373     }
374 
375     /* Private until it has a use */
376     /// Create a new `Topo`, using the graph's visitor map with *no* starting
377     /// index specified.
empty<G>(graph: G) -> Self where G: GraphRef + Visitable<NodeId = N, Map = VM>,378     fn empty<G>(graph: G) -> Self
379     where
380         G: GraphRef + Visitable<NodeId = N, Map = VM>,
381     {
382         Topo {
383             ordered: graph.visit_map(),
384             tovisit: Vec::new(),
385         }
386     }
387 
388     /// Clear visited state, and put all initial nodes in the to visit list.
reset<G>(&mut self, graph: G) where G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,389     pub fn reset<G>(&mut self, graph: G)
390     where
391         G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
392     {
393         graph.reset_map(&mut self.ordered);
394         self.tovisit.clear();
395         self.extend_with_initials(graph);
396     }
397 
398     /// Return the next node in the current topological order traversal, or
399     /// `None` if the traversal is at the end.
400     ///
401     /// *Note:* The graph may not have a complete topological order, and the only
402     /// way to know is to run the whole traversal and make sure it visits every node.
next<G>(&mut self, g: G) -> Option<N> where G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,403     pub fn next<G>(&mut self, g: G) -> Option<N>
404     where
405         G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
406     {
407         // Take an unvisited element and find which of its neighbors are next
408         while let Some(nix) = self.tovisit.pop() {
409             if self.ordered.is_visited(&nix) {
410                 continue;
411             }
412             self.ordered.visit(nix);
413             for neigh in g.neighbors(nix) {
414                 // Look at each neighbor, and those that only have incoming edges
415                 // from the already ordered list, they are the next to visit.
416                 if Reversed(g)
417                     .neighbors(neigh)
418                     .all(|b| self.ordered.is_visited(&b))
419                 {
420                     self.tovisit.push(neigh);
421                 }
422             }
423             return Some(nix);
424         }
425         None
426     }
427 }
428 
429 /// A walker is a traversal state, but where part of the traversal
430 /// information is supplied manually to each next call.
431 ///
432 /// This for example allows graph traversals that don't hold a borrow of the
433 /// graph they are traversing.
434 pub trait Walker<Context> {
435     type Item;
436     /// Advance to the next item
walk_next(&mut self, context: Context) -> Option<Self::Item>437     fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
438 
439     /// Create an iterator out of the walker and given `context`.
iter(self, context: Context) -> WalkerIter<Self, Context> where Self: Sized, Context: Clone,440     fn iter(self, context: Context) -> WalkerIter<Self, Context>
441     where
442         Self: Sized,
443         Context: Clone,
444     {
445         WalkerIter {
446             walker: self,
447             context,
448         }
449     }
450 }
451 
452 /// A walker and its context wrapped into an iterator.
453 #[derive(Clone, Debug)]
454 pub struct WalkerIter<W, C> {
455     walker: W,
456     context: C,
457 }
458 
459 impl<W, C> WalkerIter<W, C>
460 where
461     W: Walker<C>,
462     C: Clone,
463 {
context(&self) -> C464     pub fn context(&self) -> C {
465         self.context.clone()
466     }
467 
inner_ref(&self) -> &W468     pub fn inner_ref(&self) -> &W {
469         &self.walker
470     }
471 
inner_mut(&mut self) -> &mut W472     pub fn inner_mut(&mut self) -> &mut W {
473         &mut self.walker
474     }
475 }
476 
477 impl<W, C> Iterator for WalkerIter<W, C>
478 where
479     W: Walker<C>,
480     C: Clone,
481 {
482     type Item = W::Item;
next(&mut self) -> Option<Self::Item>483     fn next(&mut self) -> Option<Self::Item> {
484         self.walker.walk_next(self.context.clone())
485     }
486 }
487 
488 impl<'a, C, W: ?Sized> Walker<C> for &'a mut W
489 where
490     W: Walker<C>,
491 {
492     type Item = W::Item;
walk_next(&mut self, context: C) -> Option<Self::Item>493     fn walk_next(&mut self, context: C) -> Option<Self::Item> {
494         (**self).walk_next(context)
495     }
496 }
497 
498 impl<G> Walker<G> for Dfs<G::NodeId, G::Map>
499 where
500     G: IntoNeighbors + Visitable,
501 {
502     type Item = G::NodeId;
walk_next(&mut self, context: G) -> Option<Self::Item>503     fn walk_next(&mut self, context: G) -> Option<Self::Item> {
504         self.next(context)
505     }
506 }
507 
508 impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map>
509 where
510     G: IntoNeighbors + Visitable,
511 {
512     type Item = G::NodeId;
walk_next(&mut self, context: G) -> Option<Self::Item>513     fn walk_next(&mut self, context: G) -> Option<Self::Item> {
514         self.next(context)
515     }
516 }
517 
518 impl<G> Walker<G> for Bfs<G::NodeId, G::Map>
519 where
520     G: IntoNeighbors + Visitable,
521 {
522     type Item = G::NodeId;
walk_next(&mut self, context: G) -> Option<Self::Item>523     fn walk_next(&mut self, context: G) -> Option<Self::Item> {
524         self.next(context)
525     }
526 }
527 
528 impl<G> Walker<G> for Topo<G::NodeId, G::Map>
529 where
530     G: IntoNeighborsDirected + Visitable,
531 {
532     type Item = G::NodeId;
walk_next(&mut self, context: G) -> Option<Self::Item>533     fn walk_next(&mut self, context: G) -> Option<Self::Item> {
534         self.next(context)
535     }
536 }
537