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}