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