graph/
lib.rs

1#[macro_export]
2macro_rules! count {
3    () => (0usize);
4    ( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
5}
6
7#[macro_export]
8macro_rules! graph {
9    (
10        with_node: $node:expr,
11        with_edges: $type:tt,
12        nodes: [$($ident:expr),*],
13        connections: [ $($from:expr => {$(($cost:expr) $to:expr),+}),* ]
14    ) => {
15        graph!{
16            nodes: [$($ident => $node),*],
17            connections: [ $($from => {$(($type, $cost) {$to}),+}),* ]
18        }
19    };
20
21    (
22        nodes: [$($ident:expr => $node:expr),*],
23        connections: [ $($from:expr => {$(($type:tt, $cost:expr) {$($to:expr),+}),+}),* ]
24    ) => {{
25
26        let mut g = Graph::with_capacity(count!($($node)*), count!($($({$from;$($to)+})+)*) );
27        $(g.register($ident, $node).unwrap());*;
28        $(
29            $($(g.$type($from, $to,$cost).unwrap());+);+
30        );*;
31        g
32    }};
33}
34
35use fixedbitset::FixedBitSet;
36use num::{One, Zero};
37pub use petgraph;
38pub use petgraph::Direction;
39use petgraph::{
40    algo::Measure,
41    graph::{EdgeIndex, NodeIndex},
42    stable_graph::{DefaultIx, IndexType},
43    visit::{VisitMap, Visitable},
44    Directed, EdgeType, Graph as PGraph,
45};
46use unicase::Ascii;
47
48use std::{
49    collections::{HashMap, VecDeque},
50    fmt::Debug,
51    hash::Hash,
52    rc::Rc,
53};
54
55#[derive(Clone, Debug)]
56pub struct Step<S, Ix> {
57    pub caller: Option<Rc<Step<S, Ix>>>,
58    pub idx: NodeIndex<Ix>,
59    pub rel: Option<EdgeIndex>,
60    pub state: S,
61}
62
63#[derive(Debug)]
64pub struct StepUnit<Ix> {
65    pub caller: Option<Rc<StepUnit<Ix>>>,
66    pub idx: NodeIndex<Ix>,
67    pub rel: Option<EdgeIndex>,
68}
69
70impl<Ix: IndexType> StepUnit<Ix> {
71    pub fn from_step<S>(step: Rc<Step<S, Ix>>) -> Rc<Self> {
72        Rc::new(Self {
73            caller: step
74                .caller
75                .as_ref()
76                .and_then(|step| Some(Self::from_step(step.clone()))),
77            idx: step.idx,
78            rel: step.rel,
79        })
80    }
81    pub fn make_void<S>(step: Rc<Step<S, Ix>>) -> Step<(), Ix> {
82        Step {
83            caller: step
84                .caller
85                .as_ref()
86                .and_then(|step| Some(Rc::new(Self::make_void(step.clone())))),
87            idx: step.idx,
88            rel: step.rel,
89            state: (),
90        }
91    }
92    pub fn into_step(step: Rc<StepUnit<Ix>>) -> Step<(), Ix> {
93        Step {
94            caller: step
95                .caller
96                .as_ref()
97                .and_then(|step| Some(Rc::new(Self::into_step(step.clone())))),
98            idx: step.idx,
99            rel: step.rel,
100            state: (),
101        }
102    }
103}
104
105#[derive(Debug)]
106pub struct Steps<S, Ix = DefaultIx> {
107    start: Option<Rc<Step<S, Ix>>>,
108}
109
110impl<S: Debug, Ix: Debug> IntoIterator for Step<S, Ix> {
111    type IntoIter = Steps<S, Ix>;
112    type Item = Rc<Step<S, Ix>>;
113    fn into_iter(self) -> Self::IntoIter {
114        Steps {
115            start: Some(Rc::new(self)),
116        }
117    }
118}
119
120impl<S: Debug, Ix: Debug> Iterator for Steps<S, Ix> {
121    type Item = Rc<Step<S, Ix>>;
122    fn next(&mut self) -> Option<Self::Item> {
123        let head = self.start.clone();
124        self.start = head.as_ref().and_then(|head| head.caller.clone());
125        head.and_then(|head| Some(head))
126    }
127}
128
129impl<S, Ix> Steps<S, Ix> {
130    pub fn from_step(step: Rc<Step<S, Ix>>) -> Self {
131        Self { start: Some(step) }
132    }
133}
134
135#[derive(Debug)]
136pub enum WalkerState<S, Ix = DefaultIx> {
137    Done,
138    Found(Step<S, Ix>),
139    NotFound(Rc<Step<S, Ix>>),
140    Cutoff,
141}
142
143pub trait Walker<S, Ix = DefaultIx> {
144    fn step(&mut self) -> WalkerState<S, Ix>;
145}
146
147#[derive(Clone)]
148pub struct BreadthFirst<'a, I, N, E, Ty, Ix> {
149    goal: Option<NodeIndex<Ix>>,
150    graph: &'a Graph<I, N, E, Ty, Ix>,
151    border: VecDeque<Step<(), Ix>>,
152    visited: FixedBitSet,
153    pub direction: Direction,
154}
155
156#[derive(Clone)]
157pub struct Dijkstra<'a, F, K, I, N, E, Ty, Ix> {
158    goal: Option<NodeIndex<Ix>>,
159    graph: &'a Graph<I, N, E, Ty, Ix>,
160    border: VecDeque<Step<K, Ix>>,
161    pub direction: Direction,
162    edge_cost: F,
163}
164
165#[derive(Clone)]
166pub struct DepthFirst<'a, D, I, N, E, Ty, Ix> {
167    goal: Option<NodeIndex<Ix>>,
168    graph: &'a Graph<I, N, E, Ty, Ix>,
169    border: VecDeque<Step<D, Ix>>,
170    limit: Option<D>,
171    cutoff: bool,
172    level: D,
173    pub direction: Direction,
174}
175
176impl<'a, D: Zero, I, N, E, Ty: EdgeType, Ix: IndexType> DepthFirst<'a, D, I, N, E, Ty, Ix> {
177    #[allow(dead_code)]
178    pub fn new(
179        graph: &'a Graph<I, N, E, Ty, Ix>,
180        start: NodeIndex<Ix>,
181        goal: Option<NodeIndex<Ix>>,
182        limit: Option<D>,
183        direction: Direction,
184    ) -> Self {
185        Self {
186            graph,
187            goal,
188            limit,
189            border: {
190                let mut border = VecDeque::with_capacity(graph.node_count());
191                border.push_front(Step {
192                    caller: None,
193                    idx: start,
194                    rel: None,
195                    state: Zero::zero(),
196                });
197                border
198            },
199            cutoff: false,
200            level: Zero::zero(),
201            direction,
202        }
203    }
204}
205
206impl<'a, D, I, N, E, Ty: EdgeType, Ix: IndexType> Walker<D, Ix>
207    for DepthFirst<'a, D, I, N, E, Ty, Ix>
208where
209    D: Measure + Copy + One + Zero,
210{
211    fn step(&mut self) -> WalkerState<D, Ix> {
212        if let Some(parent) = self.border.pop_front() {
213            if self
214                .limit
215                .and_then(|limit| Some(parent.state == limit))
216                .unwrap_or(false)
217            {
218                if self
219                    .graph
220                    .inner
221                    .neighbors_directed(parent.idx.into(), self.direction)
222                    .count()
223                    != 0
224                {
225                    self.cutoff = true;
226                }
227                return WalkerState::NotFound(Rc::new(parent));
228            }
229            if self
230                .goal
231                .and_then(|goal| Some(goal == parent.idx))
232                .unwrap_or(false)
233            {
234                return WalkerState::Found(parent.clone());
235            }
236
237            let parent = Rc::new(parent);
238            self.level = parent.state + One::one();
239            for child in self
240                .graph
241                .inner
242                .neighbors_directed(parent.idx.into(), self.direction)
243            {
244                self.border.push_front(Step {
245                    caller: Some(parent.clone()),
246                    idx: child,
247                    rel: None,
248                    state: self.level,
249                })
250            }
251            WalkerState::NotFound(parent)
252        } else {
253            WalkerState::Done
254        }
255    }
256}
257
258impl<'a, F: FnMut(&E) -> K, K: Zero, I, N, E, Ty: EdgeType, Ix: IndexType>
259    Dijkstra<'a, F, K, I, N, E, Ty, Ix>
260{
261    #[allow(dead_code)]
262    pub fn new(
263        graph: &'a Graph<I, N, E, Ty, Ix>,
264        start: NodeIndex<Ix>,
265        goal: Option<NodeIndex<Ix>>,
266        direction: Direction,
267        edge_cost: F,
268    ) -> Self {
269        Self {
270            goal,
271            graph,
272            border: {
273                let mut border = VecDeque::with_capacity(graph.node_count());
274                border.push_front(Step {
275                    caller: None,
276                    idx: start,
277                    rel: None,
278                    state: Zero::zero(),
279                });
280                border
281            },
282            direction,
283            edge_cost,
284        }
285    }
286}
287
288impl<'a, F, K, I, N, E, Ty: EdgeType, Ix: IndexType> Walker<K, Ix>
289    for Dijkstra<'a, F, K, I, N, E, Ty, Ix>
290where
291    K: Measure + Copy + Ord,
292    F: FnMut(&E) -> K,
293    EdgeIndex: From<EdgeIndex<Ix>>,
294{
295    fn step(&mut self) -> WalkerState<K, Ix> {
296        if let Some(parent) = {
297            let i = self
298                .border
299                .iter()
300                .enumerate()
301                .min_by(|(_, s1), (_, s2)| s1.state.cmp(&s2.state))
302                .map(|(x, _)| x);
303            i.map(|i| self.border.remove(i).unwrap())
304        } {
305            let parent = Rc::new(parent);
306            for child_idx in self
307                .graph
308                .inner
309                .neighbors_directed(parent.idx.into(), self.direction)
310            {
311                let es_goal = self
312                    .goal
313                    .and_then(|goal| Some(goal == child_idx))
314                    .unwrap_or(false);
315                let tiene_hijos = self
316                    .graph
317                    .inner
318                    .neighbors_directed(child_idx, self.direction)
319                    .count()
320                    != 0;
321                if es_goal || tiene_hijos {
322                    let edge = self
323                        .graph
324                        .inner
325                        .find_edge_undirected(parent.idx, child_idx)
326                        .unwrap();
327                    let step = Step {
328                        caller: Some(parent.clone()),
329                        idx: child_idx.into(),
330                        rel: Some(edge.0.into()),
331                        state: parent.state + (self.edge_cost)(&self.graph.inner[edge.0]),
332                    };
333
334                    if es_goal {
335                        return WalkerState::Found(step);
336                    }
337                    self.border.push_front(step)
338                }
339            }
340            WalkerState::NotFound(parent)
341        } else {
342            WalkerState::Done
343        }
344    }
345}
346
347impl<'a, I, N, E, Ty: EdgeType, Ix: IndexType> BreadthFirst<'a, I, N, E, Ty, Ix> {
348    #[allow(dead_code)]
349    pub fn new(
350        graph: &'a Graph<I, N, E, Ty, Ix>,
351        start: NodeIndex<Ix>,
352        goal: Option<NodeIndex<Ix>>,
353        direction: Direction,
354    ) -> Self {
355        Self {
356            goal,
357            graph,
358            border: {
359                let mut border = VecDeque::with_capacity(graph.node_count());
360                border.push_front(Step {
361                    caller: None,
362                    idx: start,
363                    rel: None,
364                    state: (),
365                });
366                border
367            },
368            visited: graph.visit_map(),
369            direction,
370        }
371    }
372}
373
374impl<'a, I, N, E, Ty: EdgeType, Ix: IndexType> Walker<(), Ix>
375    for BreadthFirst<'a, I, N, E, Ty, Ix>
376{
377    fn step(&mut self) -> WalkerState<(), Ix> {
378        if let Some(parent) = self.border.pop_front() {
379            if self
380                .goal
381                .and_then(|goal| Some(goal == parent.idx))
382                .unwrap_or(false)
383            {
384                return WalkerState::Found(parent);
385            }
386
387            let parent = Rc::new(parent);
388            self.graph
389                .inner
390                .neighbors_directed(parent.idx.into(), self.direction)
391                .for_each(|child_idx| {
392                    (!self.visited.is_visited(&child_idx)).then(|| {
393                        self.visited.visit(child_idx);
394                        self.border.push_back(Step {
395                            caller: Some(parent.clone()),
396                            idx: child_idx.into(),
397                            rel: None,
398                            state: (),
399                        });
400                    });
401                });
402            WalkerState::NotFound(parent)
403        } else {
404            WalkerState::Done
405        }
406    }
407}
408
409/// The library's principal Graph structure.
410///
411/// The struct is an abstract layer built on top of the
412/// [`petgraph::Graph<N, E, Ty, Ix>`](../petgraph/graph/struct.Graph.html)
413/// implementation to support named nodes using `I` identifiers
414///
415/// - `I` is the type used for identifying the nodes, because of its purpose only values that implement
416/// [`Copy`](https://doc.rust-lang.org/1.66.1/core/marker/trait.Copy.html) are allowed like `&'static str`
417/// or {`u8`, `i8`, ...}. If the identifier is a number it is better
418/// to just use [`petgraph::Graph`] since its default
419/// behaviour is to work identifying nodes with numbers, these numbers are named indexes and don't add any overhead
420/// like this more high-level API which uses a `HashMap`.
421/// - `N` is the type used to store values within the graph's nodes
422/// - `E` is the type used to store values within the graph's edges
423/// - `Ty` is the Graph connection type. [`petgraph::Directed`](../petgraph/enum.Directed.html) by default
424/// - `Ix` is the number type value used as indexer for Edges and Nodes.
425pub struct Graph<I, N, E, Ty = Directed, Ix = DefaultIx> {
426    /// The inner [`petgraph::Graph<N, E, Ty, Ix>`](../petgraph/graph/struct.Graph.html)
427    inner: PGraph<N, E, Ty, Ix>,
428    /// The map of the `I` node-name to the [`NodeIndex<Ix>`](../petgraph/graph/struct.NodeIndex.html)
429    pub nodes: HashMap<Ascii<I>, NodeIndex<Ix>>,
430}
431
432impl<I, N, E, Ty, Ix> Graph<I, N, E, Ty, Ix>
433where
434    Ty: EdgeType,
435    Ix: IndexType,
436{
437    /// The Graph constructor
438    pub fn new() -> Self {
439        Self {
440            inner: PGraph::<N, E, Ty, Ix>::default(),
441            nodes: HashMap::new(),
442        }
443    }
444
445    /// Construct a new Graph with a fixed initial size.
446    /// Since we use a macro to construct the graph we do call this constructor
447    /// to save a couple calls to the allocator
448    pub fn with_capacity(nodes: usize, edges: usize) -> Self {
449        Self {
450            inner: PGraph::with_capacity(nodes, edges),
451            nodes: HashMap::with_capacity(nodes),
452        }
453    }
454
455    pub fn node_count(&self) -> usize {
456        self.inner.node_count()
457    }
458
459    pub fn edge_count(&self) -> usize {
460        self.inner.edge_count()
461    }
462
463    pub fn visit_map(&self) -> FixedBitSet {
464        self.inner.visit_map()
465    }
466}
467
468impl<I, N, E, Ty: EdgeType, Ix: IndexType> Graph<I, N, E, Ty, Ix>
469where
470    I: Copy + Hash + Eq,
471    Ascii<I>: Copy + Hash + Eq,
472    NodeIndex: From<NodeIndex<Ix>>,
473    EdgeIndex: From<EdgeIndex<Ix>>,
474{
475    /// Get the high-level node name from the low-level node index. E.g. NodeIndex(0) -> "Arad"
476    pub fn index_name<'a>(&'a self, value: NodeIndex<Ix>) -> Option<I> {
477        self.nodes.iter().find_map(|(key, val)| {
478            if val == &value {
479                Some(key.into_inner())
480            } else {
481                None
482            }
483        })
484    }
485
486    /// Get the low-level node index from the high-level node name. E.g. "Arad" -> NodeIndex(0)
487    pub fn name_index(&self, ident: I) -> Option<NodeIndex<Ix>> {
488        self.nodes.get(&Ascii::new(ident)).copied()
489    }
490
491    /// Connect to nodes by their high-level names. E.g. "Arad" -> "Neamt"
492    ///
493    /// The method calls the necessary low-level methods to connect both node indexes
494    /// within the inner graph.
495    ///
496    /// Adds values to the inner graph's `Vec<Edge<E, Ix>>` to represent neighbors between nodes
497    /// and the binded `E` value
498    pub fn next(&mut self, from: I, to: I, edge: E) -> Result<(), ()>
499    where
500        I: Debug,
501    {
502        match (self.name_index(from), self.name_index(to)) {
503            (Some(fidx), Some(tidx)) => {
504                self.inner.add_edge(fidx.into(), tidx.into(), edge);
505                Ok(())
506            }
507            (None, None) => panic!("Los nodos {:?} y {:?} no existen", from, to),
508            (None, Some(_)) => panic!("El nodo {:?} no existe", from),
509            (Some(_), None) => panic!("El nodo {:?} no existe", to),
510        }
511    }
512
513    /// Register a node with a given name and stored `N` value
514    ///
515    /// The method calls the necessary low-level methods to connect both node indexes
516    /// within the inner graph.
517    ///
518    /// Adds values to the inner graph's `Vec<Node<N, Ix>>` to represent neighbors between nodes
519    /// and the binded `N` value
520    pub fn register(&mut self, ident: I, node: N) -> Result<(), ()>
521    where
522        I: Debug,
523    {
524        let ascii = Ascii::new(ident);
525        if self.nodes.contains_key(&ascii) {
526            panic!("El nodo {:?} ya existe", ident);
527        } else {
528            let ix = self.inner.add_node(node);
529            self.nodes.insert(ascii, ix);
530            Ok(())
531        }
532    }
533
534    pub fn iterative_depth_first<D>(
535        &self,
536        start: I,
537        goal: Option<I>,
538        limit: Option<D>,
539    ) -> Result<Step<D, Ix>, ()>
540    where
541        D: Measure + Copy + One + Zero,
542    {
543        match goal {
544            Some(goal) => {
545                match (self.name_index(start), self.name_index(goal)) {
546                    (Some(fidx), Some(tidx)) => {
547                        let mut cur_limit: D = One::one();
548                        loop {
549                            if limit
550                                .and_then(|limit| Some(limit == cur_limit))
551                                .unwrap_or(false)
552                            {
553                                return Err(());
554                            }
555                            match self.depth_first_impl::<D>(fidx, Some(tidx), Some(cur_limit)) {
556                            Ok(res) => {
557                                return Ok(res);
558                            }
559                            Err(err) => match err {
560                                WalkerState::Done => {
561                                    return Err(());
562                                }
563                                WalkerState::Cutoff => {
564                                    cur_limit = cur_limit + One::one();
565                                    continue;
566                                },
567                                _ => unreachable!("Only WalkerState::Done and WalkerState::Cutoff are returned")
568                            },
569                        }
570                        }
571                    }
572                    (None, None) => Err(()),
573                    (None, Some(_)) => Err(()),
574                    (Some(_), None) => Err(()),
575                }
576            }
577            _ => match self.name_index(start) {
578                Some(fidx) => self.depth_first_impl(fidx, None, limit).map_err(|_| ()),
579                _ => Err(()),
580            },
581        }
582    }
583
584    pub fn depth_first<D>(
585        &self,
586        start: I,
587        goal: Option<I>,
588        limit: Option<D>,
589    ) -> Result<Step<D, Ix>, ()>
590    where
591        D: Measure + Copy + One + Zero,
592    {
593        match goal {
594            Some(goal) => match (self.name_index(start), self.name_index(goal)) {
595                (Some(fidx), Some(tidx)) => self
596                    .depth_first_impl::<D>(fidx, Some(tidx), limit)
597                    .map_err(|_| ()),
598                (None, None) => Err(()),
599                (None, Some(_)) => Err(()),
600                (Some(_), None) => Err(()),
601            },
602            _ => match self.name_index(start) {
603                Some(fidx) => self.depth_first_impl(fidx, None, limit).map_err(|_| ()),
604                _ => Err(()),
605            },
606        }
607    }
608
609    pub fn depth_first_impl<D>(
610        &self,
611        start: NodeIndex<Ix>,
612        goal: Option<NodeIndex<Ix>>,
613        limit: Option<D>,
614    ) -> Result<Step<D, Ix>, WalkerState<D, Ix>>
615    where
616        D: Measure + Copy + One + Zero + Debug,
617    {
618        let mut border = VecDeque::with_capacity(self.node_count());
619        border.push_front(Step {
620            caller: None,
621            idx: start,
622            rel: None,
623            state: Zero::zero(),
624        });
625        let mut cutoff = false;
626        let mut nivel;
627
628        while let Some(parent) = border.pop_front() {
629            if limit
630                .and_then(|limit| Some(parent.state == limit))
631                .unwrap_or(false)
632            {
633                if self
634                    .inner
635                    .neighbors_directed(parent.idx.into(), Direction::Outgoing)
636                    .count()
637                    != 0
638                {
639                    cutoff = true;
640                }
641                continue;
642            }
643            if goal
644                .and_then(|goal| Some(goal == parent.idx))
645                .unwrap_or(false)
646            {
647                return Ok(parent.clone());
648            }
649
650            nivel = parent.state + One::one();
651            for child in self
652                .inner
653                .neighbors_directed(parent.idx.into(), petgraph::Direction::Outgoing)
654            {
655                border.push_front(Step {
656                    caller: Some(Rc::new(parent.clone())),
657                    idx: child,
658                    rel: None,
659                    state: nivel,
660                })
661            }
662        }
663
664        if cutoff {
665            Err(WalkerState::Cutoff)
666        } else {
667            Err(WalkerState::Done)
668        }
669    }
670
671    pub fn breadth_first(&self, start: I, goal: Option<I>) -> Result<Steps<(), Ix>, ()> {
672        match goal {
673            Some(goal) => match (self.name_index(start), self.name_index(goal)) {
674                (Some(fidx), Some(tidx)) => self.breadth_first_impl(fidx, Some(tidx)),
675                (None, None) => Err(()),
676                (None, Some(_)) => Err(()),
677                (Some(_), None) => Err(()),
678            },
679            _ => match self.name_index(start) {
680                Some(fidx) => self.breadth_first_impl(fidx, None),
681                _ => Err(()),
682            },
683        }
684    }
685
686    pub fn dijkstra<K, F>(
687        &self,
688        start: I,
689        goal: Option<I>,
690        edge_cost: F,
691    ) -> Result<Steps<K, Ix>, ()>
692    where
693        K: Measure + Copy + Eq + Default + Ord + PartialOrd,
694        F: FnMut(&E) -> K,
695    {
696        match goal {
697            Some(goal) => match (self.name_index(start), self.name_index(goal)) {
698                (Some(fidx), Some(tidx)) => self.dijkstra_impl(fidx, Some(tidx), edge_cost),
699                (None, None) => Err(()),
700                (None, Some(_)) => Err(()),
701                (Some(_), None) => Err(()),
702            },
703            _ => match self.name_index(start) {
704                Some(fidx) => self.dijkstra_impl(fidx, None, edge_cost),
705                _ => Err(()),
706            },
707        }
708    }
709
710    pub fn dijkstra_impl<'a, K, F>(
711        &self,
712        start: NodeIndex<Ix>,
713        goal: Option<NodeIndex<Ix>>,
714        mut edge_cost: F,
715    ) -> Result<Steps<K, Ix>, ()>
716    where
717        K: Measure + Copy + Eq + Default + Ord + PartialOrd,
718        F: FnMut(&E) -> K,
719    {
720        let mut border = VecDeque::with_capacity(self.inner.node_count());
721        border.push_front(Step {
722            caller: None,
723            idx: start,
724            rel: None,
725            state: K::default(),
726        });
727
728        while let Some(parent) = {
729            let i = border
730                .iter()
731                .enumerate()
732                .min_by(|(_, s1), (_, s2)| s1.state.cmp(&s2.state))
733                .map(|(x, _)| x);
734            i.map(|i| border.remove(i).unwrap())
735        } {
736            if goal
737                .and_then(|goal| Some(goal == parent.idx))
738                .unwrap_or(false)
739            {
740                return Ok(parent.into_iter());
741            }
742
743            let parent = Rc::new(parent);
744            for child_idx in self
745                .inner
746                .neighbors_directed(parent.idx.into(), petgraph::Direction::Outgoing)
747            {
748                let es_goal = goal
749                    .and_then(|goal| Some(goal == child_idx))
750                    .unwrap_or(false);
751                let tiene_hijos = self
752                    .inner
753                    .neighbors_directed(child_idx, petgraph::Direction::Outgoing)
754                    .count()
755                    != 0;
756                if es_goal || tiene_hijos {
757                    let edge = self.inner.find_edge(parent.idx, child_idx).unwrap();
758                    let step = Step {
759                        caller: Some(parent.clone()),
760                        idx: child_idx.into(),
761                        rel: Some(edge.into()),
762                        state: parent.state + edge_cost(&self.inner[edge]),
763                    };
764
765                    if es_goal {
766                        return Ok(step.into_iter());
767                    }
768                    border.push_front(step)
769                }
770            }
771        }
772        Err(())
773    }
774
775    pub fn breadth_first_impl(
776        &self,
777        start: NodeIndex<Ix>,
778        goal: Option<NodeIndex<Ix>>,
779    ) -> Result<Steps<(), Ix>, ()> {
780        let mut border = VecDeque::with_capacity(self.inner.node_count());
781        let mut visited = self.inner.visit_map();
782        border.push_front(Step {
783            caller: None,
784            idx: start,
785            rel: None,
786            state: (),
787        });
788
789        while let Some(parent) = border.pop_front() {
790            if goal
791                .and_then(|goal| Some(goal == parent.idx))
792                .unwrap_or(false)
793            {
794                return Ok(parent.into_iter());
795            }
796
797            if self
798                .inner
799                .neighbors_directed(parent.idx.into(), petgraph::Direction::Outgoing)
800                .count()
801                != 0
802            {
803                let parent = Rc::new(parent);
804                self.inner
805                    .neighbors_directed(parent.idx.into(), petgraph::Direction::Outgoing)
806                    .for_each(|child_idx| {
807                        (!visited.is_visited(&child_idx)).then(|| {
808                            visited.visit(child_idx);
809                            border.push_back(Step {
810                                caller: Some(parent.clone()),
811                                idx: child_idx.into(),
812                                rel: None,
813                                state: (),
814                            });
815                        });
816                    });
817            }
818        }
819        Err(())
820    }
821
822    pub fn bidirectional<S: Debug, D: Debug>(
823        &self,
824        mut algo1: impl Walker<S, Ix>,
825        mut algo2: impl Walker<D, Ix>,
826    ) -> Result<Step<(), Ix>, ()> {
827        let mut res1;
828        let mut res2;
829        let mut visited1 = self.visit_map();
830        let mut visited2 = self.visit_map();
831
832        let mut steps1: HashMap<_, Rc<StepUnit<_>>> = HashMap::new();
833        let mut steps2: HashMap<_, Rc<StepUnit<_>>> = HashMap::new();
834
835        let mut last_step_1 = None;
836        let mut last_step_2 = None;
837        // let mut i = 0;
838        let matching_on = loop {
839            // i += 1;
840            // println!("{i}");
841            res1 = algo1.step();
842            res2 = algo2.step();
843
844            if let WalkerState::NotFound(ref node) = res1 {
845                visited1.visit(node.idx);
846                steps1.insert(node.idx, StepUnit::from_step(node.clone()));
847                last_step_1 = Some(StepUnit::from_step(node.clone()));
848                if visited2.is_visited(&node.idx) {
849                    break 1;
850                }
851            }
852
853            if let WalkerState::NotFound(ref node) = res2 {
854                visited2.visit(node.idx);
855                steps2.insert(node.idx, StepUnit::from_step(node.clone()));
856                last_step_2 = Some(StepUnit::from_step(node.clone()));
857                if visited1.is_visited(&node.idx) {
858                    break 2;
859                }
860            }
861
862            if matches!(&res1, WalkerState::Done) && matches!(&res2, WalkerState::Done) {
863                return Err(());
864            }
865
866            if let WalkerState::Found(node) = res1 {
867                return Ok(StepUnit::make_void(Rc::new(node)));
868            }
869            if let WalkerState::Found(node) = res2 {
870                return Ok(StepUnit::make_void(Rc::new(node)));
871            }
872        };
873
874        // println!("Break on {}", matching_on);
875        if let (Some(mut last1), Some(mut last2)) = (last_step_1, last_step_2) {
876            let mut trace1 = VecDeque::new();
877            let mut trace2 = VecDeque::new();
878
879            let res1_p = (&mut last1, &mut steps1);
880            let res2_p = (&mut last2, &mut steps2);
881            if matching_on == 1 {
882                *res2_p.0 = res2_p.1.get(&res1_p.0.idx).unwrap().clone();
883            } else {
884                *res1_p.0 = res1_p.1.get(&res2_p.0.idx).unwrap().clone();
885            }
886
887            // println!("***1");
888            let mut last1 = Some(last1);
889            while let Some(i) = last1 {
890                trace1.push_back(i.clone());
891                // println!("{:?}", self.index_name(i.idx));
892                last1 = i.caller.clone();
893            }
894            // println!("***2");
895            let mut last2 = Some(last2);
896            while let Some(i) = last2 {
897                trace2.push_back(i.clone());
898                // println!("{:?}", self.index_name(i.idx));
899                last2 = i.caller.clone();
900            }
901
902            // println!("***3");
903            for i in trace1.range(1..) {
904                trace2.push_front(i.clone());
905            }
906
907            let first = trace2.pop_front().unwrap();
908            let mut result = Step {
909                caller: None,
910                idx: first.idx,
911                rel: None,
912                state: (),
913            };
914
915            while let Some(i) = trace2.pop_front() {
916                result = Step {
917                    caller: Some(Rc::new(result.clone())),
918                    idx: i.idx,
919                    state: (),
920                    rel: i.rel,
921                }
922            }
923            Ok(result)
924        } else {
925            unreachable!("This point should always have valid last steps")
926        }
927    }
928}
929
930#[cfg(test)]
931mod tests {
932    use super::*;
933
934    #[test]
935    fn test_depth() {
936        let graph = final_grap();
937        let a = graph
938            .depth_first::<u32>("Cancun", Some("Cabo San Lucas"), None)
939            .unwrap();
940
941        for node in a {
942            println!("{:#?}", graph.index_name(node.idx).unwrap());
943        }
944    }
945
946    #[test]
947    fn test_breadth() {
948        let graph = final_grap();
949        let a = graph
950            .breadth_first("Cancun", Some("Cabo San Lucas"))
951            .unwrap();
952
953        for node in a {
954            println!("{:#?}", graph.index_name(node.idx).unwrap());
955        }
956    }
957
958    #[test]
959    fn test_breadth_walker() {
960        let graph = final_grap();
961        let mut a = BreadthFirst::new(
962            &graph,
963            graph.name_index("Cabo San Lucas").unwrap(),
964            Some(graph.name_index("Cancun").unwrap()),
965            Direction::Incoming,
966        );
967
968        let a = {
969            loop {
970                match a.step() {
971                    WalkerState::Found(result) => {
972                        break Some(result.into_iter());
973                    }
974                    WalkerState::Done => {
975                        break None;
976                    }
977                    _ => {}
978                }
979            }
980        }
981        .unwrap();
982
983        for node in a {
984            println!("{:#?}", graph.index_name(node.idx).unwrap());
985        }
986    }
987
988    #[test]
989    fn test_dijkstra() {
990        let graph = final_grap();
991        let a = graph
992            .dijkstra("Cancun", Some("Felipe Carrillo Puerto"), |state| *state)
993            .unwrap();
994
995        for node in a {
996            println!("{:#?}", graph.index_name(node.idx).unwrap());
997        }
998    }
999
1000    #[test]
1001    fn test_dijkstra_walker() {
1002        let graph = final_grap();
1003        let mut a = Dijkstra::new(
1004            &graph,
1005            graph.name_index("Felipe Carrillo Puerto").unwrap(),
1006            Some(graph.name_index("Cancun").unwrap()),
1007            Direction::Incoming,
1008            |state| *state,
1009        );
1010
1011        let a = {
1012            // let mut i = 0;
1013            loop {
1014                // i += 1;
1015                // println!("{i}");
1016                match a.step() {
1017                    WalkerState::Found(result) => {
1018                        break Some(result.into_iter());
1019                    }
1020                    WalkerState::Done => {
1021                        break None;
1022                    }
1023                    _ => {}
1024                }
1025            }
1026        }
1027        .unwrap();
1028
1029        for node in a {
1030            println!("{:#?}", graph.index_name(node.idx).unwrap());
1031        }
1032    }
1033
1034    #[test]
1035    fn test_bidirectional() {
1036        let graph = final_grap();
1037
1038        let a = BreadthFirst::new(
1039            &graph,
1040            graph.name_index("Cancun").unwrap(),
1041            Some(graph.name_index("Cabo San Lucas").unwrap()),
1042            Direction::Outgoing,
1043        );
1044        let b = DepthFirst::new(
1045            &graph,
1046            graph.name_index("Cancun").unwrap(),
1047            Some(graph.name_index("Cabo San Lucas").unwrap()),
1048            None::<usize>,
1049            Direction::Incoming,
1050        );
1051
1052        let res = graph.bidirectional(a, b).unwrap();
1053        for node in res {
1054            println!("{:#?}", graph.index_name(node.idx).unwrap());
1055        }
1056    }
1057
1058    fn final_grap() -> Graph<&'static str, (), u16> {
1059        let graph: Graph<&'static str, (), u16> = graph! {
1060            with_node: (),
1061            with_edges: next,
1062            nodes: [
1063                "Acapulco",        "Villa Hermosa",      "Guanajuato",     "Cancun",
1064                "Chilpancingo",     "Aguaprieta",   "Alvarado",      "Valladolid",
1065                "Acayucan",     "Santa Ana",     "Oaxaca",    "Chetumal",
1066                "Tehuantepec",   "Aguascalientes",     "Atlacomulco",   "Campeche",
1067                "Tuxtla",      "Guadalajara",      "Queretaro",       "Felipe Carrillo Puerto",
1068                "Merida", "Chihuahua", "Janos", "Juarez", "Ojinaga", "Iguala", "Ciudad Altamirano",
1069                "Cuernavaca", "Toluca de Lerdo", "Zihuatanejo", "Ciudad del Carmen", "Ciudad Obregon",
1070                "Guaymas", "Ciudad Victoria", "Matamoros", "Soto la Marina", "Tampico", "Colima",
1071                "Morelia", "Playa Azul", "Cordoba", "Veracruz", "Culiacan", "Hidalgo del Parral",
1072                "Topolobampo", "Durango", "Mazatlan", "Torreon", "Ensenada", "San Quintin" , "Francisco Escarcega",
1073                "Manzanillo", "Salamanca", "Hermosillo", "San Luis Potosi", "Izucar de Matamoros", "La Paz",
1074                "Cabo San Lucas", "Reynosa", "Mexicalli", "San Felipe", "Tijuana", "Ciudad de Mexico", "Pachuca de Soto",
1075                "Puebla", "Tlaxcala", "Monclova", "Piedras Negras", "Monterrey", "Nuevo Laredo" , "Puerto Angel",
1076                "Tehuacan", "Tuxpan de Rodriguez Cano", "Pinotepa Nacional", "Zacatecas", "Santa Rosalia", "Santo Domingo", "Tepic", "Ciudad Juarez"
1077
1078            ],
1079            connections: [
1080                "Cancun" => {(90) "Valladolid", (100) "Felipe Carrillo Puerto"},
1081                "Valladolid" => {(90) "Felipe Carrillo Puerto"},
1082                "Felipe Carrillo Puerto" => {(60) "Campeche"},
1083                "Campeche" => {(90) "Merida", (100) "Chetumal", (90) "Ciudad del Carmen"},
1084                "Chetumal" => {(111) "Francisco Escarcega"},
1085                "Ciudad del Carmen" => {(90) "Villa Hermosa", (90) "Tuxtla"},
1086                "Villa Hermosa" => {(90) "Acayucan"},
1087                "Tuxtla" => {(90) "Acayucan"},
1088                "Acayucan" => {(80) "Tehuantepec", (110) "Alvarado"},
1089                "Alvarado" => {(100) "Oaxaca"},
1090                "Oaxaca" => {(80) "Tehuacan", (90) "Puerto Angel", (90) "Izucar de Matamoros"},
1091                "Puerto Angel" => {(100) "Pinotepa Nacional" },
1092                "Izucar de Matamoros" => {(90) "Puebla", (100) "Cuernavaca"},
1093                "Pinotepa Nacional" => {(100) "Acapulco"},
1094                "Cuernavaca" => {(100) "Ciudad de Mexico", (100) "Ciudad Altamirano"},
1095                "Puebla" => {(90) "Ciudad de Mexico", (80) "Cordoba"},
1096                "Acapulco" => {(140) "Chilpancingo"},
1097                "Ciudad de Mexico" => {(100) "Tlaxcala", (110) "Toluca de Lerdo", (90) "Queretaro", (100) "Pachuca de Soto"},
1098                "Ciudad Altamirano" => {(90) "Zihuatanejo"},
1099                "Cordoba" => {(90) "Veracruz"},
1100                "Chilpancingo" => {(90) "Iguala"},
1101                "Toluca de Lerdo" => {(100) "Ciudad Altamirano"},
1102                "Queretaro" => {(90) "Atlacomulco", (90) "Salamanca", (90) "San Luis Potosi"},
1103                "Pachuca de Soto" => {(110) "Tuxpan de Rodriguez Cano"},
1104                "Zihuatanejo" => {(90) "Playa Azul"},
1105                "Iguala" => {(100) "Cuernavaca", (110) "Ciudad Altamirano"},
1106                "Salamanca" => {(90) "Guanajuato", (90) "Guadalajara"},
1107                "San Luis Potosi" => {(90) "Zacatecas", (70) "Durango", (100) "Aguascalientes" },
1108                "Tuxpan de Rodriguez Cano" => {(100) "Tampico"},
1109                "Playa Azul" => {(100) "Morelia", (100) "Colima", (100) "Manzanillo"},
1110                "Guanajuato" => {(80) "Aguascalientes"},
1111                "Guadalajara" => {(110) "Tepic"},
1112                "Aguascalientes" =>{(70) "Guadalajara"},
1113                "Durango" => {(90) "Hidalgo del Parral", (90) "Mazatlan"},
1114                "Tampico" => {(80) "Ciudad Victoria"},
1115                "Morelia" => {(90) "Salamanca"},
1116                "Manzanillo" => {(50) "Colima", (80) "Guadalajara"},
1117                "Colima" => {(90) "Morelia", (50) "Guadalajara"},
1118                "Tepic" =>{(50) "Mazatlan"},
1119                "Hidalgo del Parral" => {(130) "Chihuahua", (110) "Topolobampo", (80) "Culiacan"},
1120                "Mazatlan" => {(90) "Culiacan"},
1121                "Ciudad Victoria" => {(80) "Soto la Marina", (80) "Matamoros", (80) "Monterrey", (80) "Durango"},
1122                "Chihuahua" => {(90) "Ciudad Juarez", (90) "Janos"},
1123                "Topolobampo" => {(90) "Ciudad Obregon"},
1124                "Culiacan" => {(110) "Topolobampo"},
1125                "Matamoros" => {(90) "Reynosa"},
1126                "Monterrey" => {(110) "Nuevo Laredo",(70) "Monclova"},
1127                "Janos" => {(110) "Aguaprieta"},
1128                "Ciudad Obregon" => {(80) "Guaymas"},
1129                "Reynosa" => {(100) "Nuevo Laredo"},
1130                "Nuevo Laredo" => {(100) "Piedras Negras"},
1131                "Monclova" => {(100) "Torreon", (90) "Ojinaga"},
1132                "Aguaprieta" => {(90) "Santa Ana"},
1133                "Guaymas" => {(90) "Hermosillo"},
1134                "Piedras Negras" => {(90) "Monclova"},
1135                "Torreon" => {(90) "Durango"},
1136                "Ojinaga" => {(90) "Chihuahua"},
1137                "Santa Ana" => {(159) "Mexicalli"},
1138                "Hermosillo" => {(100) "Santa Ana"},
1139                "Mexicalli" => {(50) "Tijuana", (70) "San Felipe"},
1140                "Tijuana" => {(30) "Ensenada"},
1141                "San Felipe" => {(50) "Ensenada"},
1142                "Ensenada" => {(90) "San Quintin"},
1143                "San Quintin" => {(140) "Santa Rosalia"},
1144                "Santa Rosalia" => {(100) "Santo Domingo"},
1145                "Santo Domingo" => {(100) "La Paz"},
1146                "La Paz" => {(40) "Cabo San Lucas"}
1147            ]
1148        };
1149        graph
1150    }
1151}