Skip to main content

petgraph/algo/
mod.rs

1//! Graph algorithms.
2//!
3//! It is a goal to gradually migrate the algorithms to be based on graph traits
4//! so that they are generally applicable. For now, some of these still require
5//! the `Graph` type.
6
7pub mod dominators;
8pub mod tred;
9
10#[cfg(feature = "std")]
11use std::{cmp::min, collections::{BinaryHeap, HashMap, VecDeque}, fmt::Debug, ops::Add};
12
13#[cfg(not(feature = "std"))]
14use core::{cmp::min, fmt::Debug, ops::Add};
15
16#[cfg(not(feature = "std"))]
17use alloc::{collections::{BinaryHeap, BTreeMap as HashMap}, vec::Vec, collections::vec_deque::VecDeque};
18
19use crate::prelude::*;
20
21use super::graph::IndexType;
22use super::unionfind::UnionFind;
23use super::visit::{
24    GraphBase, GraphRef, IntoEdgeReferences, IntoEdges, IntoNeighbors, IntoNeighborsDirected,
25    IntoNodeIdentifiers, NodeCompactIndexable, NodeCount, NodeIndexable, Reversed, VisitMap,
26    Visitable,
27};
28use super::EdgeType;
29use crate::data::Element;
30use crate::scored::MinScored;
31use crate::visit::Walker;
32use crate::visit::{Data, IntoNodeReferences, NodeRef};
33
34pub use super::astar::astar;
35pub use super::dijkstra::dijkstra;
36#[cfg(feature = "graphmap")]
37pub use super::k_shortest_path::k_shortest_path;
38
39pub use super::isomorphism::{
40    is_isomorphic, is_isomorphic_matching, is_isomorphic_subgraph, is_isomorphic_subgraph_matching,
41};
42#[cfg(feature = "graphmap")]
43pub use super::simple_paths::all_simple_paths;
44
45/// \[Generic\] Return the number of connected components of the graph.
46///
47/// For a directed graph, this is the *weakly* connected components.
48/// # Example
49/// ```rust
50/// use petgraph::Graph;
51/// use petgraph::algo::connected_components;
52/// use petgraph::prelude::*;
53///
54/// let mut graph : Graph<(),(),Directed>= Graph::new();
55/// let a = graph.add_node(()); // node with no weight
56/// let b = graph.add_node(());
57/// let c = graph.add_node(());
58/// let d = graph.add_node(());
59/// let e = graph.add_node(());
60/// let f = graph.add_node(());
61/// let g = graph.add_node(());
62/// let h = graph.add_node(());
63///
64/// graph.extend_with_edges(&[
65///     (a, b),
66///     (b, c),
67///     (c, d),
68///     (d, a),
69///     (e, f),
70///     (f, g),
71///     (g, h),
72///     (h, e)
73/// ]);
74/// // a ----> b       e ----> f
75/// // ^       |       ^       |
76/// // |       v       |       v
77/// // d <---- c       h <---- g
78///
79/// assert_eq!(connected_components(&graph),2);
80/// graph.add_edge(b,e,());
81/// assert_eq!(connected_components(&graph),1);
82/// ```
83pub fn connected_components<G>(g: G) -> usize
84where
85    G: NodeCompactIndexable + IntoEdgeReferences,
86{
87    let mut vertex_sets = UnionFind::new(g.node_bound());
88    for edge in g.edge_references() {
89        let (a, b) = (edge.source(), edge.target());
90
91        // union the two vertices of the edge
92        vertex_sets.union(g.to_index(a), g.to_index(b));
93    }
94    let mut labels = vertex_sets.into_labeling();
95    labels.sort();
96    labels.dedup();
97    labels.len()
98}
99
100/// \[Generic\] Return `true` if the input graph contains a cycle.
101///
102/// Always treats the input graph as if undirected.
103pub fn is_cyclic_undirected<G>(g: G) -> bool
104where
105    G: NodeIndexable + IntoEdgeReferences,
106{
107    let mut edge_sets = UnionFind::new(g.node_bound());
108    for edge in g.edge_references() {
109        let (a, b) = (edge.source(), edge.target());
110
111        // union the two vertices of the edge
112        //  -- if they were already the same, then we have a cycle
113        if !edge_sets.union(g.to_index(a), g.to_index(b)) {
114            return true;
115        }
116    }
117    false
118}
119
120/// \[Generic\] Perform a topological sort of a directed graph.
121///
122/// If the graph was acyclic, return a vector of nodes in topological order:
123/// each node is ordered before its successors.
124/// Otherwise, it will return a `Cycle` error. Self loops are also cycles.
125///
126/// To handle graphs with cycles, use the scc algorithms or `DfsPostOrder`
127/// instead of this function.
128///
129/// If `space` is not `None`, it is used instead of creating a new workspace for
130/// graph traversal. The implementation is iterative.
131pub fn toposort<G>(
132    g: G,
133    space: Option<&mut DfsSpace<G::NodeId, G::Map>>,
134) -> Result<Vec<G::NodeId>, Cycle<G::NodeId>>
135where
136    G: IntoNeighborsDirected + IntoNodeIdentifiers + Visitable,
137{
138    // based on kosaraju scc
139    with_dfs(g, space, |dfs| {
140        dfs.reset(g);
141        let mut finished = g.visit_map();
142
143        let mut finish_stack = Vec::new();
144        for i in g.node_identifiers() {
145            if dfs.discovered.is_visited(&i) {
146                continue;
147            }
148            dfs.stack.push(i);
149            while let Some(&nx) = dfs.stack.last() {
150                if dfs.discovered.visit(nx) {
151                    // First time visiting `nx`: Push neighbors, don't pop `nx`
152                    for succ in g.neighbors(nx) {
153                        if succ == nx {
154                            // self cycle
155                            return Err(Cycle(nx));
156                        }
157                        if !dfs.discovered.is_visited(&succ) {
158                            dfs.stack.push(succ);
159                        }
160                    }
161                } else {
162                    dfs.stack.pop();
163                    if finished.visit(nx) {
164                        // Second time: All reachable nodes must have been finished
165                        finish_stack.push(nx);
166                    }
167                }
168            }
169        }
170        finish_stack.reverse();
171
172        dfs.reset(g);
173        for &i in &finish_stack {
174            dfs.move_to(i);
175            let mut cycle = false;
176            while let Some(j) = dfs.next(Reversed(g)) {
177                if cycle {
178                    return Err(Cycle(j));
179                }
180                cycle = true;
181            }
182        }
183
184        Ok(finish_stack)
185    })
186}
187
188/// \[Generic\] Return `true` if the input directed graph contains a cycle.
189///
190/// This implementation is recursive; use `toposort` if an alternative is
191/// needed.
192pub fn is_cyclic_directed<G>(g: G) -> bool
193where
194    G: IntoNodeIdentifiers + IntoNeighbors + Visitable,
195{
196    use crate::visit::{depth_first_search, DfsEvent};
197
198    depth_first_search(g, g.node_identifiers(), |event| match event {
199        DfsEvent::BackEdge(_, _) => Err(()),
200        _ => Ok(()),
201    })
202    .is_err()
203}
204
205type DfsSpaceType<G> = DfsSpace<<G as GraphBase>::NodeId, <G as Visitable>::Map>;
206
207/// Workspace for a graph traversal.
208#[derive(Clone, Debug)]
209pub struct DfsSpace<N, VM> {
210    dfs: Dfs<N, VM>,
211}
212
213impl<N, VM> DfsSpace<N, VM>
214where
215    N: Copy + PartialEq,
216    VM: VisitMap<N>,
217{
218    pub fn new<G>(g: G) -> Self
219    where
220        G: GraphRef + Visitable<NodeId = N, Map = VM>,
221    {
222        DfsSpace { dfs: Dfs::empty(g) }
223    }
224}
225
226impl<N, VM> Default for DfsSpace<N, VM>
227where
228    VM: VisitMap<N> + Default,
229{
230    fn default() -> Self {
231        DfsSpace {
232            dfs: Dfs {
233                stack: <_>::default(),
234                discovered: <_>::default(),
235            },
236        }
237    }
238}
239
240/// Create a Dfs if it's needed
241fn with_dfs<G, F, R>(g: G, space: Option<&mut DfsSpaceType<G>>, f: F) -> R
242where
243    G: GraphRef + Visitable,
244    F: FnOnce(&mut Dfs<G::NodeId, G::Map>) -> R,
245{
246    let mut local_visitor;
247    let dfs = if let Some(v) = space {
248        &mut v.dfs
249    } else {
250        local_visitor = Dfs::empty(g);
251        &mut local_visitor
252    };
253    f(dfs)
254}
255
256/// \[Generic\] Check if there exists a path starting at `from` and reaching `to`.
257///
258/// If `from` and `to` are equal, this function returns true.
259///
260/// If `space` is not `None`, it is used instead of creating a new workspace for
261/// graph traversal.
262pub fn has_path_connecting<G>(
263    g: G,
264    from: G::NodeId,
265    to: G::NodeId,
266    space: Option<&mut DfsSpace<G::NodeId, G::Map>>,
267) -> bool
268where
269    G: IntoNeighbors + Visitable,
270{
271    with_dfs(g, space, |dfs| {
272        dfs.reset(g);
273        dfs.move_to(from);
274        dfs.iter(g).any(|x| x == to)
275    })
276}
277
278/// Renamed to `kosaraju_scc`.
279#[deprecated(note = "renamed to kosaraju_scc")]
280pub fn scc<G>(g: G) -> Vec<Vec<G::NodeId>>
281where
282    G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
283{
284    kosaraju_scc(g)
285}
286
287/// \[Generic\] Compute the *strongly connected components* using [Kosaraju's algorithm][1].
288///
289/// [1]: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm
290///
291/// Return a vector where each element is a strongly connected component (scc).
292/// The order of node ids within each scc is arbitrary, but the order of
293/// the sccs is their postorder (reverse topological sort).
294///
295/// For an undirected graph, the sccs are simply the connected components.
296///
297/// This implementation is iterative and does two passes over the nodes.
298pub fn kosaraju_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
299where
300    G: IntoNeighborsDirected + Visitable + IntoNodeIdentifiers,
301{
302    let mut dfs = DfsPostOrder::empty(g);
303
304    // First phase, reverse dfs pass, compute finishing times.
305    // http://stackoverflow.com/a/26780899/161659
306    let mut finish_order = Vec::with_capacity(0);
307    for i in g.node_identifiers() {
308        if dfs.discovered.is_visited(&i) {
309            continue;
310        }
311
312        dfs.move_to(i);
313        while let Some(nx) = dfs.next(Reversed(g)) {
314            finish_order.push(nx);
315        }
316    }
317
318    let mut dfs = Dfs::from_parts(dfs.stack, dfs.discovered);
319    dfs.reset(g);
320    let mut sccs = Vec::new();
321
322    // Second phase
323    // Process in decreasing finishing time order
324    for i in finish_order.into_iter().rev() {
325        if dfs.discovered.is_visited(&i) {
326            continue;
327        }
328        // Move to the leader node `i`.
329        dfs.move_to(i);
330        let mut scc = Vec::new();
331        while let Some(nx) = dfs.next(g) {
332            scc.push(nx);
333        }
334        sccs.push(scc);
335    }
336    sccs
337}
338
339#[derive(Copy, Clone, Debug)]
340struct NodeData {
341    index: Option<usize>,
342    lowlink: usize,
343    on_stack: bool,
344}
345
346/// A reusable state for computing the *strongly connected components* using [Tarjan's algorithm][1].
347///
348/// [1]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
349#[derive(Debug)]
350pub struct TarjanScc<N> {
351    index: usize,
352    nodes: Vec<NodeData>,
353    stack: Vec<N>,
354}
355
356impl<N> Default for TarjanScc<N> {
357    fn default() -> Self {
358        Self::new()
359    }
360}
361
362impl<N> TarjanScc<N> {
363    /// Creates a new `TarjanScc`
364    pub fn new() -> Self {
365        TarjanScc {
366            index: 0,
367            nodes: Vec::new(),
368            stack: Vec::new(),
369        }
370    }
371
372    /// \[Generic\] Compute the *strongly connected components* using [Tarjan's algorithm][1].
373    ///
374    /// [1]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
375    ///
376    /// Calls `f` for each strongly strongly connected component (scc).
377    /// The order of node ids within each scc is arbitrary, but the order of
378    /// the sccs is their postorder (reverse topological sort).
379    ///
380    /// For an undirected graph, the sccs are simply the connected components.
381    ///
382    /// This implementation is recursive and does one pass over the nodes.
383    pub fn run<G, F>(&mut self, g: G, mut f: F)
384    where
385        G: IntoNodeIdentifiers<NodeId = N> + IntoNeighbors<NodeId = N> + NodeIndexable<NodeId = N>,
386        F: FnMut(&[N]),
387        N: Copy + PartialEq,
388    {
389        self.nodes.clear();
390        self.nodes.resize(
391            g.node_bound(),
392            NodeData {
393                index: None,
394                lowlink: !0,
395                on_stack: false,
396            },
397        );
398
399        for n in g.node_identifiers() {
400            self.visit(n, g, &mut f);
401        }
402
403        debug_assert!(self.stack.is_empty());
404    }
405
406    fn visit<G, F>(&mut self, v: G::NodeId, g: G, f: &mut F)
407    where
408        G: IntoNeighbors<NodeId = N> + NodeIndexable<NodeId = N>,
409        F: FnMut(&[N]),
410        N: Copy + PartialEq,
411    {
412        macro_rules! node {
413            ($node:expr) => {
414                self.nodes[g.to_index($node)]
415            };
416        }
417
418        let node_v = &mut node![v];
419        if node_v.index.is_some() {
420            // already visited
421            return;
422        }
423
424        let v_index = self.index;
425        node_v.index = Some(v_index);
426        node_v.lowlink = v_index;
427        node_v.on_stack = true;
428        self.stack.push(v);
429        self.index += 1;
430
431        for w in g.neighbors(v) {
432            let node_w = &mut node![w];
433            match node_w.index {
434                None => {
435                    self.visit(w, g, f);
436                    node![v].lowlink = min(node![v].lowlink, node![w].lowlink);
437                }
438                Some(w_index) => {
439                    if node_w.on_stack {
440                        // Successor w is in stack S and hence in the current SCC
441                        let v_lowlink = &mut node![v].lowlink;
442                        *v_lowlink = min(*v_lowlink, w_index);
443                    }
444                }
445            }
446        }
447
448        // If v is a root node, pop the stack and generate an SCC
449        let node_v = &mut node![v];
450        if let Some(v_index) = node_v.index {
451            if node_v.lowlink == v_index {
452                let nodes = &mut self.nodes;
453                let start = self
454                    .stack
455                    .iter()
456                    .rposition(|&w| {
457                        nodes[g.to_index(w)].on_stack = false;
458                        g.to_index(w) == g.to_index(v)
459                    })
460                    .unwrap();
461                f(&self.stack[start..]);
462                self.stack.truncate(start);
463            }
464        }
465    }
466}
467
468/// \[Generic\] Compute the *strongly connected components* using [Tarjan's algorithm][1].
469///
470/// [1]: https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
471///
472/// Return a vector where each element is a strongly connected component (scc).
473/// The order of node ids within each scc is arbitrary, but the order of
474/// the sccs is their postorder (reverse topological sort).
475///
476/// For an undirected graph, the sccs are simply the connected components.
477///
478/// This implementation is recursive and does one pass over the nodes.
479pub fn tarjan_scc<G>(g: G) -> Vec<Vec<G::NodeId>>
480where
481    G: IntoNodeIdentifiers + IntoNeighbors + NodeIndexable,
482{
483    let mut sccs = Vec::new();
484    {
485        let mut tarjan_scc = TarjanScc::new();
486        tarjan_scc.run(g, |scc| sccs.push(scc.iter().cloned().rev().collect()));
487    }
488    sccs
489}
490
491/// [Graph] Condense every strongly connected component into a single node and return the result.
492///
493/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
494/// the output is acyclic.
495/// # Example
496/// ```rust
497/// use petgraph::Graph;
498/// use petgraph::algo::condensation;
499/// use petgraph::prelude::*;
500///
501/// let mut graph : Graph<(),(),Directed> = Graph::new();
502/// let a = graph.add_node(()); // node with no weight
503/// let b = graph.add_node(());
504/// let c = graph.add_node(());
505/// let d = graph.add_node(());
506/// let e = graph.add_node(());
507/// let f = graph.add_node(());
508/// let g = graph.add_node(());
509/// let h = graph.add_node(());
510///
511/// graph.extend_with_edges(&[
512///     (a, b),
513///     (b, c),
514///     (c, d),
515///     (d, a),
516///     (b, e),
517///     (e, f),
518///     (f, g),
519///     (g, h),
520///     (h, e)
521/// ]);
522///
523/// // a ----> b ----> e ----> f
524/// // ^       |       ^       |
525/// // |       v       |       v
526/// // d <---- c       h <---- g
527///
528/// let condensed_graph = condensation(graph,false);
529/// let A = NodeIndex::new(0);
530/// let B = NodeIndex::new(1);
531/// assert_eq!(condensed_graph.node_count(), 2);
532/// assert_eq!(condensed_graph.edge_count(), 9);
533/// assert_eq!(condensed_graph.neighbors(A).collect::<Vec<_>>(), vec![A, A, A, A]);
534/// assert_eq!(condensed_graph.neighbors(B).collect::<Vec<_>>(), vec![A, B, B, B, B]);
535/// ```
536/// If `make_acyclic` is true, self-loops and multi edges are ignored:
537///
538/// ```rust
539/// # use petgraph::Graph;
540/// # use petgraph::algo::condensation;
541/// # use petgraph::prelude::*;
542/// #
543/// # let mut graph : Graph<(),(),Directed> = Graph::new();
544/// # let a = graph.add_node(()); // node with no weight
545/// # let b = graph.add_node(());
546/// # let c = graph.add_node(());
547/// # let d = graph.add_node(());
548/// # let e = graph.add_node(());
549/// # let f = graph.add_node(());
550/// # let g = graph.add_node(());
551/// # let h = graph.add_node(());
552/// #
553/// # graph.extend_with_edges(&[
554/// #    (a, b),
555/// #    (b, c),
556/// #    (c, d),
557/// #    (d, a),
558/// #    (b, e),
559/// #    (e, f),
560/// #    (f, g),
561/// #    (g, h),
562/// #    (h, e)
563/// # ]);
564/// let acyclic_condensed_graph = condensation(graph, true);
565/// let A = NodeIndex::new(0);
566/// let B = NodeIndex::new(1);
567/// assert_eq!(acyclic_condensed_graph.node_count(), 2);
568/// assert_eq!(acyclic_condensed_graph.edge_count(), 1);
569/// assert_eq!(acyclic_condensed_graph.neighbors(B).collect::<Vec<_>>(), vec![A]);
570/// ```
571pub fn condensation<N, E, Ty, Ix>(
572    g: Graph<N, E, Ty, Ix>,
573    make_acyclic: bool,
574) -> Graph<Vec<N>, E, Ty, Ix>
575where
576    Ty: EdgeType,
577    Ix: IndexType,
578{
579    let sccs = kosaraju_scc(&g);
580    let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());
581
582    // Build a map from old indices to new ones.
583    let mut node_map = vec![NodeIndex::end(); g.node_count()];
584    for comp in sccs {
585        let new_nix = condensed.add_node(Vec::new());
586        for nix in comp {
587            node_map[nix.index()] = new_nix;
588        }
589    }
590
591    // Consume nodes and edges of the old graph and insert them into the new one.
592    let (nodes, edges) = g.into_nodes_edges();
593    for (nix, node) in nodes.into_iter().enumerate() {
594        condensed[node_map[nix]].push(node.weight);
595    }
596    for edge in edges {
597        let source = node_map[edge.source().index()];
598        let target = node_map[edge.target().index()];
599        if make_acyclic {
600            if source != target {
601                condensed.update_edge(source, target, edge.weight);
602            }
603        } else {
604            condensed.add_edge(source, target, edge.weight);
605        }
606    }
607    condensed
608}
609
610/// \[Generic\] Compute a *minimum spanning tree* of a graph.
611///
612/// The input graph is treated as if undirected.
613///
614/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
615/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
616/// component of the graph.
617///
618/// The resulting graph has all the vertices of the input graph (with identical node indices),
619/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
620///
621/// Use `from_elements` to create a graph from the resulting iterator.
622pub fn min_spanning_tree<G>(g: G) -> MinSpanningTree<G>
623where
624    G::NodeWeight: Clone,
625    G::EdgeWeight: Clone + PartialOrd,
626    G: IntoNodeReferences + IntoEdgeReferences + NodeIndexable,
627{
628    // Initially each vertex is its own disjoint subgraph, track the connectedness
629    // of the pre-MST with a union & find datastructure.
630    let subgraphs = UnionFind::new(g.node_bound());
631
632    let edges = g.edge_references();
633    let mut sort_edges = BinaryHeap::with_capacity(edges.size_hint().0);
634    for edge in edges {
635        sort_edges.push(MinScored(
636            edge.weight().clone(),
637            (edge.source(), edge.target()),
638        ));
639    }
640
641    MinSpanningTree {
642        graph: g,
643        node_ids: Some(g.node_references()),
644        subgraphs,
645        sort_edges,
646        node_map: HashMap::new(),
647        node_count: 0,
648    }
649}
650
651/// An iterator producing a minimum spanning forest of a graph.
652pub struct MinSpanningTree<G>
653where
654    G: Data + IntoNodeReferences,
655{
656    graph: G,
657    node_ids: Option<G::NodeReferences>,
658    subgraphs: UnionFind<usize>,
659    sort_edges: BinaryHeap<MinScored<G::EdgeWeight, (G::NodeId, G::NodeId)>>,
660    node_map: HashMap<usize, usize>,
661    node_count: usize,
662}
663
664impl<G> Iterator for MinSpanningTree<G>
665where
666    G: IntoNodeReferences + NodeIndexable,
667    G::NodeWeight: Clone,
668    G::EdgeWeight: PartialOrd,
669{
670    type Item = Element<G::NodeWeight, G::EdgeWeight>;
671
672    fn next(&mut self) -> Option<Self::Item> {
673        let g = self.graph;
674        if let Some(ref mut iter) = self.node_ids {
675            if let Some(node) = iter.next() {
676                self.node_map.insert(g.to_index(node.id()), self.node_count);
677                self.node_count += 1;
678                return Some(Element::Node {
679                    weight: node.weight().clone(),
680                });
681            }
682        }
683        self.node_ids = None;
684
685        // Kruskal's algorithm.
686        // Algorithm is this:
687        //
688        // 1. Create a pre-MST with all the vertices and no edges.
689        // 2. Repeat:
690        //
691        //  a. Remove the shortest edge from the original graph.
692        //  b. If the edge connects two disjoint trees in the pre-MST,
693        //     add the edge.
694        while let Some(MinScored(score, (a, b))) = self.sort_edges.pop() {
695            // check if the edge would connect two disjoint parts
696            let (a_index, b_index) = (g.to_index(a), g.to_index(b));
697            if self.subgraphs.union(a_index, b_index) {
698                let (&a_order, &b_order) =
699                    match (self.node_map.get(&a_index), self.node_map.get(&b_index)) {
700                        (Some(a_id), Some(b_id)) => (a_id, b_id),
701                        _ => panic!("Edge references unknown node"),
702                    };
703                return Some(Element::Edge {
704                    source: a_order,
705                    target: b_order,
706                    weight: score,
707                });
708            }
709        }
710        None
711    }
712}
713
714/// An algorithm error: a cycle was found in the graph.
715#[derive(Clone, Debug, PartialEq)]
716pub struct Cycle<N>(N);
717
718impl<N> Cycle<N> {
719    /// Return a node id that participates in the cycle
720    pub fn node_id(&self) -> N
721    where
722        N: Copy,
723    {
724        self.0
725    }
726}
727/// An algorithm error: a cycle of negative weights was found in the graph.
728#[derive(Clone, Debug, PartialEq)]
729pub struct NegativeCycle(());
730
731/// \[Generic\] Compute shortest paths from node `source` to all other.
732///
733/// Using the [Bellman–Ford algorithm][bf]; negative edge costs are
734/// permitted, but the graph must not have a cycle of negative weights
735/// (in that case it will return an error).
736///
737/// On success, return one vec with path costs, and another one which points
738/// out the predecessor of a node along a shortest path. The vectors
739/// are indexed by the graph's node indices.
740///
741/// [bf]: https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm
742///
743/// # Example
744/// ```rust
745/// use petgraph::Graph;
746/// use petgraph::algo::bellman_ford;
747/// use petgraph::prelude::*;
748///
749/// let mut g = Graph::new();
750/// let a = g.add_node(()); // node with no weight
751/// let b = g.add_node(());
752/// let c = g.add_node(());
753/// let d = g.add_node(());
754/// let e = g.add_node(());
755/// let f = g.add_node(());
756/// g.extend_with_edges(&[
757///     (0, 1, 2.0),
758///     (0, 3, 4.0),
759///     (1, 2, 1.0),
760///     (1, 5, 7.0),
761///     (2, 4, 5.0),
762///     (4, 5, 1.0),
763///     (3, 4, 1.0),
764/// ]);
765///
766/// // Graph represented with the weight of each edge
767/// //
768/// //     2       1
769/// // a ----- b ----- c
770/// // | 4     | 7     |
771/// // d       f       | 5
772/// // | 1     | 1     |
773/// // \------ e ------/
774///
775/// let path = bellman_ford(&g, a);
776/// assert_eq!(path, Ok((vec![0.0 ,     2.0,    3.0,    4.0,     5.0,     6.0],
777///                      vec![None, Some(a),Some(b),Some(a), Some(d), Some(e)]
778///                    ))
779///           );
780/// // Node f (indice 5) can be reach from a with a path costing 6.
781/// // Predecessor of f is Some(e) which predecessor is Some(d) which predecessor is Some(a).
782/// // Thus the path from a to f is a <-> d <-> e <-> f
783///
784/// let graph_with_neg_cycle = Graph::<(), f32, Undirected>::from_edges(&[
785///         (0, 1, -2.0),
786///         (0, 3, -4.0),
787///         (1, 2, -1.0),
788///         (1, 5, -25.0),
789///         (2, 4, -5.0),
790///         (4, 5, -25.0),
791///         (3, 4, -1.0),
792/// ]);
793///
794/// assert!(bellman_ford(&graph_with_neg_cycle, NodeIndex::new(0)).is_err());
795/// ```
796pub fn bellman_ford<G>(
797    g: G,
798    source: G::NodeId,
799) -> Result<(Vec<G::EdgeWeight>, Vec<Option<G::NodeId>>), NegativeCycle>
800where
801    G: NodeCount + IntoNodeIdentifiers + IntoEdges + NodeIndexable,
802    G::EdgeWeight: FloatMeasure,
803{
804    let mut predecessor = vec![None; g.node_bound()];
805    let mut distance = vec![<_>::infinite(); g.node_bound()];
806
807    let ix = |i| g.to_index(i);
808
809    distance[ix(source)] = <_>::zero();
810    // scan up to |V| - 1 times.
811    for _ in 1..g.node_count() {
812        let mut did_update = false;
813        for i in g.node_identifiers() {
814            for edge in g.edges(i) {
815                let i = edge.source();
816                let j = edge.target();
817                let w = *edge.weight();
818                if distance[ix(i)] + w < distance[ix(j)] {
819                    distance[ix(j)] = distance[ix(i)] + w;
820                    predecessor[ix(j)] = Some(i);
821                    did_update = true;
822                }
823            }
824        }
825        if !did_update {
826            break;
827        }
828    }
829
830    // check for negative weight cycle
831    for i in g.node_identifiers() {
832        for edge in g.edges(i) {
833            let j = edge.target();
834            let w = *edge.weight();
835            if distance[ix(i)] + w < distance[ix(j)] {
836                //println!("neg cycle, detected from {} to {}, weight={}", i, j, w);
837                return Err(NegativeCycle(()));
838            }
839        }
840    }
841
842    Ok((distance, predecessor))
843}
844
845/// Return `true` if the graph is bipartite. A graph is bipartite if it's nodes can be divided into
846/// two disjoint and indepedent sets U and V such that every edge connects U to one in V. This
847/// algorithm implements 2-coloring algorithm based on the BFS algorithm.
848///
849/// Always treats the input graph as if undirected.
850pub fn is_bipartite_undirected<G, N, VM>(g: G, start: N) -> bool
851where
852    G: GraphRef + Visitable<NodeId = N, Map = VM> + IntoNeighbors<NodeId = N>,
853    N: Copy + PartialEq + Debug,
854    VM: VisitMap<N>,
855{
856    let mut red = g.visit_map();
857    red.visit(start);
858    let mut blue = g.visit_map();
859
860    let mut stack = VecDeque::new();
861    stack.push_front(start);
862
863    while let Some(node) = stack.pop_front() {
864        let is_red = red.is_visited(&node);
865        let is_blue = blue.is_visited(&node);
866
867        assert!(is_red ^ is_blue);
868
869        for neighbour in g.neighbors(node) {
870            let is_neigbour_red = red.is_visited(&neighbour);
871            let is_neigbour_blue = blue.is_visited(&neighbour);
872
873            if (is_red && is_neigbour_red) || (is_blue && is_neigbour_blue) {
874                return false;
875            }
876
877            if !is_neigbour_red && !is_neigbour_blue {
878                //hasn't been visited yet
879
880                match (is_red, is_blue) {
881                    (true, false) => {
882                        blue.visit(neighbour);
883                    }
884                    (false, true) => {
885                        red.visit(neighbour);
886                    }
887                    (_, _) => {
888                        panic!("Invariant doesn't hold");
889                    }
890                }
891
892                stack.push_back(neighbour);
893            }
894        }
895    }
896
897    true
898}
899
900/// Associated data that can be used for measures (such as length).
901pub trait Measure: Debug + PartialOrd + Add<Self, Output = Self> + Default + Clone {}
902
903impl<M> Measure for M where M: Debug + PartialOrd + Add<M, Output = M> + Default + Clone {}
904
905/// A floating-point measure.
906pub trait FloatMeasure: Measure + Copy {
907    fn zero() -> Self;
908    fn infinite() -> Self;
909}
910
911impl FloatMeasure for f32 {
912    fn zero() -> Self {
913        0.
914    }
915    fn infinite() -> Self {
916        1. / 0.
917    }
918}
919
920impl FloatMeasure for f64 {
921    fn zero() -> Self {
922        0.
923    }
924    fn infinite() -> Self {
925        1. / 0.
926    }
927}