1use super::{GraphRef, IntoNodeIdentifiers, Reversed};
2use super::{IntoNeighbors, IntoNeighborsDirected, VisitMap, Visitable};
3use crate::Incoming;
4use std::collections::VecDeque;
5
6#[derive(Clone, Debug)]
37pub struct Dfs<N, VM> {
38 pub stack: Vec<N>,
40 pub discovered: VM,
42}
43
44impl<N, VM> Default for Dfs<N, VM>
45where
46 VM: Default,
47{
48 fn default() -> Self {
49 Dfs {
50 stack: Vec::new(),
51 discovered: VM::default(),
52 }
53 }
54}
55
56impl<N, VM> Dfs<N, VM>
57where
58 N: Copy + PartialEq,
59 VM: VisitMap<N>,
60{
61 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 pub fn from_parts(stack: Vec<N>, discovered: VM) -> Self {
74 Dfs { stack, discovered }
75 }
76
77 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 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 pub fn move_to(&mut self, start: N) {
100 self.stack.clear();
101 self.stack.push(start);
102 }
103
104 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#[derive(Clone, Debug)]
131pub struct DfsPostOrder<N, VM> {
132 pub stack: Vec<N>,
134 pub discovered: VM,
136 pub finished: VM,
138}
139
140impl<N, VM> Default for DfsPostOrder<N, VM>
141where
142 VM: Default,
143{
144 fn default() -> Self {
145 DfsPostOrder {
146 stack: Vec::new(),
147 discovered: VM::default(),
148 finished: VM::default(),
149 }
150 }
151}
152
153impl<N, VM> DfsPostOrder<N, VM>
154where
155 N: Copy + PartialEq,
156 VM: VisitMap<N>,
157{
158 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 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 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 pub fn move_to(&mut self, start: N) {
194 self.stack.clear();
195 self.stack.push(start);
196 }
197
198 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 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 return Some(nx);
216 }
217 }
218 }
219 None
220 }
221}
222
223#[derive(Clone)]
253pub struct Bfs<N, VM> {
254 pub stack: VecDeque<N>,
256 pub discovered: VM,
258}
259
260impl<N, VM> Default for Bfs<N, VM>
261where
262 VM: Default,
263{
264 fn default() -> Self {
265 Bfs {
266 stack: VecDeque::new(),
267 discovered: VM::default(),
268 }
269 }
270}
271
272impl<N, VM> Bfs<N, VM>
273where
274 N: Copy + PartialEq,
275 VM: VisitMap<N>,
276{
277 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 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#[derive(Clone)]
314pub struct Topo<N, VM> {
315 tovisit: Vec<N>,
316 ordered: VM,
317}
318
319impl<N, VM> Default for Topo<N, VM>
320where
321 VM: Default,
322{
323 fn default() -> Self {
324 Topo {
325 tovisit: Vec::new(),
326 ordered: VM::default(),
327 }
328 }
329}
330
331impl<N, VM> Topo<N, VM>
332where
333 N: Copy + PartialEq,
334 VM: VisitMap<N>,
335{
336 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 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
364 fn extend_with_initials<G>(&mut self, g: G)
365 where
366 G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,
367 {
368 self.tovisit.extend(
370 g.node_identifiers()
371 .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()),
372 );
373 }
374
375 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 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 pub fn next<G>(&mut self, g: G) -> Option<N>
404 where
405 G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
406 {
407 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 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
429pub trait Walker<Context> {
435 type Item;
436 fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
438
439 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#[derive(Clone, Debug)]
454pub struct WalkerIter<W, C> {
455 walker: W,
456 context: C,
457}
458
459impl<W, C> WalkerIter<W, C>
460where
461 W: Walker<C>,
462 C: Clone,
463{
464 pub fn context(&self) -> C {
465 self.context.clone()
466 }
467
468 pub fn inner_ref(&self) -> &W {
469 &self.walker
470 }
471
472 pub fn inner_mut(&mut self) -> &mut W {
473 &mut self.walker
474 }
475}
476
477impl<W, C> Iterator for WalkerIter<W, C>
478where
479 W: Walker<C>,
480 C: Clone,
481{
482 type Item = W::Item;
483 fn next(&mut self) -> Option<Self::Item> {
484 self.walker.walk_next(self.context.clone())
485 }
486}
487
488impl<C, W: ?Sized> Walker<C> for &mut W
489where
490 W: Walker<C>,
491{
492 type Item = W::Item;
493 fn walk_next(&mut self, context: C) -> Option<Self::Item> {
494 (**self).walk_next(context)
495 }
496}
497
498impl<G> Walker<G> for Dfs<G::NodeId, G::Map>
499where
500 G: IntoNeighbors + Visitable,
501{
502 type Item = G::NodeId;
503 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
504 self.next(context)
505 }
506}
507
508impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map>
509where
510 G: IntoNeighbors + Visitable,
511{
512 type Item = G::NodeId;
513 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
514 self.next(context)
515 }
516}
517
518impl<G> Walker<G> for Bfs<G::NodeId, G::Map>
519where
520 G: IntoNeighbors + Visitable,
521{
522 type Item = G::NodeId;
523 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
524 self.next(context)
525 }
526}
527
528impl<G> Walker<G> for Topo<G::NodeId, G::Map>
529where
530 G: IntoNeighborsDirected + Visitable,
531{
532 type Item = G::NodeId;
533 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
534 self.next(context)
535 }
536}