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 fn extend_with_initials<G>(&mut self, g: G)
348 where
349 G: IntoNodeIdentifiers + IntoNeighborsDirected<NodeId = N>,
350 {
351 self.tovisit.extend(
353 g.node_identifiers()
354 .filter(move |&a| g.neighbors_directed(a, Incoming).next().is_none()),
355 );
356 }
357
358 fn empty<G>(graph: G) -> Self
362 where
363 G: GraphRef + Visitable<NodeId = N, Map = VM>,
364 {
365 Topo {
366 ordered: graph.visit_map(),
367 tovisit: Vec::new(),
368 }
369 }
370
371 pub fn reset<G>(&mut self, graph: G)
373 where
374 G: IntoNodeIdentifiers + IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
375 {
376 graph.reset_map(&mut self.ordered);
377 self.tovisit.clear();
378 self.extend_with_initials(graph);
379 }
380
381 pub fn next<G>(&mut self, g: G) -> Option<N>
387 where
388 G: IntoNeighborsDirected + Visitable<NodeId = N, Map = VM>,
389 {
390 while let Some(nix) = self.tovisit.pop() {
392 if self.ordered.is_visited(&nix) {
393 continue;
394 }
395 self.ordered.visit(nix);
396 for neigh in g.neighbors(nix) {
397 if Reversed(g)
400 .neighbors(neigh)
401 .all(|b| self.ordered.is_visited(&b))
402 {
403 self.tovisit.push(neigh);
404 }
405 }
406 return Some(nix);
407 }
408 None
409 }
410}
411
412pub trait Walker<Context> {
418 type Item;
419 fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
421
422 fn iter(self, context: Context) -> WalkerIter<Self, Context>
424 where
425 Self: Sized,
426 Context: Clone,
427 {
428 WalkerIter {
429 walker: self,
430 context,
431 }
432 }
433}
434
435#[derive(Clone, Debug)]
437pub struct WalkerIter<W, C> {
438 walker: W,
439 context: C,
440}
441
442impl<W, C> WalkerIter<W, C>
443where
444 W: Walker<C>,
445 C: Clone,
446{
447 pub fn context(&self) -> C {
448 self.context.clone()
449 }
450
451 pub fn inner_ref(&self) -> &W {
452 &self.walker
453 }
454
455 pub fn inner_mut(&mut self) -> &mut W {
456 &mut self.walker
457 }
458}
459
460impl<W, C> Iterator for WalkerIter<W, C>
461where
462 W: Walker<C>,
463 C: Clone,
464{
465 type Item = W::Item;
466 fn next(&mut self) -> Option<Self::Item> {
467 self.walker.walk_next(self.context.clone())
468 }
469}
470
471impl<'a, C, W: ?Sized> Walker<C> for &'a mut W
472where
473 W: Walker<C>,
474{
475 type Item = W::Item;
476 fn walk_next(&mut self, context: C) -> Option<Self::Item> {
477 (**self).walk_next(context)
478 }
479}
480
481impl<G> Walker<G> for Dfs<G::NodeId, G::Map>
482where
483 G: IntoNeighbors + Visitable,
484{
485 type Item = G::NodeId;
486 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
487 self.next(context)
488 }
489}
490
491impl<G> Walker<G> for DfsPostOrder<G::NodeId, G::Map>
492where
493 G: IntoNeighbors + Visitable,
494{
495 type Item = G::NodeId;
496 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
497 self.next(context)
498 }
499}
500
501impl<G> Walker<G> for Bfs<G::NodeId, G::Map>
502where
503 G: IntoNeighbors + Visitable,
504{
505 type Item = G::NodeId;
506 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
507 self.next(context)
508 }
509}
510
511impl<G> Walker<G> for Topo<G::NodeId, G::Map>
512where
513 G: IntoNeighborsDirected + Visitable,
514{
515 type Item = G::NodeId;
516 fn walk_next(&mut self, context: G) -> Option<Self::Item> {
517 self.next(context)
518 }
519}