use std::cmp; use std::fmt; use std::hash::Hash; use std::iter; use std::marker::PhantomData; use std::mem::size_of; use std::ops::{Index, IndexMut, Range}; use std::slice; use fixedbitset::FixedBitSet; use crate::{Directed, Direction, EdgeType, Incoming, IntoWeightedEdge, Outgoing, Undirected}; use crate::iter_format::{DebugMap, IterFormatExt, NoPretty}; use crate::util::enumerate; use crate::visit; #[cfg(feature = "serde-1")] mod serialization; /// The default integer type for graph indices. /// `u32` is the default to reduce the size of the graph's data and improve /// performance in the common case. /// /// Used for node and edge indices in `Graph` and `StableGraph`, used /// for node indices in `Csr`. pub type DefaultIx = u32; /// Trait for the unsigned integer type used for node and edge indices. /// /// # Safety /// /// Marked `unsafe` because: the trait must faithfully preserve /// and convert index values. pub unsafe trait IndexType: Copy + Default + Hash + Ord + fmt::Debug + 'static { fn new(x: usize) -> Self; fn index(&self) -> usize; fn max() -> Self; } unsafe impl IndexType for usize { #[inline(always)] fn new(x: usize) -> Self { x } #[inline(always)] fn index(&self) -> Self { *self } #[inline(always)] fn max() -> Self { ::std::usize::MAX } } unsafe impl IndexType for u32 { #[inline(always)] fn new(x: usize) -> Self { x as u32 } #[inline(always)] fn index(&self) -> usize { *self as usize } #[inline(always)] fn max() -> Self { ::std::u32::MAX } } unsafe impl IndexType for u16 { #[inline(always)] fn new(x: usize) -> Self { x as u16 } #[inline(always)] fn index(&self) -> usize { *self as usize } #[inline(always)] fn max() -> Self { ::std::u16::MAX } } unsafe impl IndexType for u8 { #[inline(always)] fn new(x: usize) -> Self { x as u8 } #[inline(always)] fn index(&self) -> usize { *self as usize } #[inline(always)] fn max() -> Self { ::std::u8::MAX } } /// Node identifier. #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct NodeIndex(Ix); impl NodeIndex { #[inline] pub fn new(x: usize) -> Self { NodeIndex(IndexType::new(x)) } #[inline] pub fn index(self) -> usize { self.0.index() } #[inline] pub fn end() -> Self { NodeIndex(IndexType::max()) } fn _into_edge(self) -> EdgeIndex { EdgeIndex(self.0) } } unsafe impl IndexType for NodeIndex { fn index(&self) -> usize { self.0.index() } fn new(x: usize) -> Self { NodeIndex::new(x) } fn max() -> Self { NodeIndex(::max()) } } impl From for NodeIndex { fn from(ix: Ix) -> Self { NodeIndex(ix) } } impl fmt::Debug for NodeIndex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "NodeIndex({:?})", self.0) } } /// Short version of `NodeIndex::new` pub fn node_index(index: usize) -> NodeIndex { NodeIndex::new(index) } /// Short version of `EdgeIndex::new` pub fn edge_index(index: usize) -> EdgeIndex { EdgeIndex::new(index) } /// Edge identifier. #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)] pub struct EdgeIndex(Ix); impl EdgeIndex { #[inline] pub fn new(x: usize) -> Self { EdgeIndex(IndexType::new(x)) } #[inline] pub fn index(self) -> usize { self.0.index() } /// An invalid `EdgeIndex` used to denote absence of an edge, for example /// to end an adjacency list. #[inline] pub fn end() -> Self { EdgeIndex(IndexType::max()) } fn _into_node(self) -> NodeIndex { NodeIndex(self.0) } } impl From for EdgeIndex { fn from(ix: Ix) -> Self { EdgeIndex(ix) } } impl fmt::Debug for EdgeIndex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "EdgeIndex({:?})", self.0) } } /* * FIXME: Use this impl again, when we don't need to add so many bounds impl fmt::Debug for EdgeIndex { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "EdgeIndex(")); if *self == EdgeIndex::end() { try!(write!(f, "End")); } else { try!(write!(f, "{}", self.index())); } write!(f, ")") } } */ const DIRECTIONS: [Direction; 2] = [Outgoing, Incoming]; /// The graph's node type. #[derive(Debug)] pub struct Node { /// Associated node data. pub weight: N, /// Next edge in outgoing and incoming edge lists. next: [EdgeIndex; 2], } impl Clone for Node where E: Clone, Ix: Copy, { clone_fields!(Node, weight, next,); } impl Node { /// Accessor for data structure internals: the first edge in the given direction. pub fn next_edge(&self, dir: Direction) -> EdgeIndex { self.next[dir.index()] } } /// The graph's edge type. #[derive(Debug)] pub struct Edge { /// Associated edge data. pub weight: E, /// Next edge in outgoing and incoming edge lists. next: [EdgeIndex; 2], /// Start and End node index node: [NodeIndex; 2], } impl Clone for Edge where E: Clone, Ix: Copy, { clone_fields!(Edge, weight, next, node,); } impl Edge { /// Accessor for data structure internals: the next edge for the given direction. pub fn next_edge(&self, dir: Direction) -> EdgeIndex { self.next[dir.index()] } /// Return the source node index. pub fn source(&self) -> NodeIndex { self.node[0] } /// Return the target node index. pub fn target(&self) -> NodeIndex { self.node[1] } } /// `Graph` is a graph datastructure using an adjacency list representation. /// /// `Graph` is parameterized over: /// /// - Associated data `N` for nodes and `E` for edges, called *weights*. /// The associated data can be of arbitrary type. /// - Edge type `Ty` that determines whether the graph edges are directed or undirected. /// - Index type `Ix`, which determines the maximum size of the graph. /// /// The `Graph` is a regular Rust collection and is `Send` and `Sync` (as long /// as associated data `N` and `E` are). /// /// The graph uses **O(|V| + |E|)** space, and allows fast node and edge insert, /// efficient graph search and graph algorithms. /// It implements **O(e')** edge lookup and edge and node removals, where **e'** /// is some local measure of edge count. /// Based on the graph datastructure used in rustc. /// /// Here's an example of building a graph with directed edges, and below /// an illustration of how it could be rendered with graphviz (see /// [`Dot`](../dot/struct.Dot.html)): /// /// ``` /// use petgraph::Graph; /// /// let mut deps = Graph::<&str, &str>::new(); /// let pg = deps.add_node("petgraph"); /// let fb = deps.add_node("fixedbitset"); /// let qc = deps.add_node("quickcheck"); /// let rand = deps.add_node("rand"); /// let libc = deps.add_node("libc"); /// deps.extend_with_edges(&[ /// (pg, fb), (pg, qc), /// (qc, rand), (rand, libc), (qc, libc), /// ]); /// ``` /// /// ![graph-example](https://bluss.github.io/ndarray/images/graph-example.svg) /// /// ### Graph Indices /// /// The graph maintains indices for nodes and edges, and node and edge /// weights may be accessed mutably. Indices range in a compact interval, for /// example for *n* nodes indices are 0 to *n* - 1 inclusive. /// /// `NodeIndex` and `EdgeIndex` are types that act as references to nodes and edges, /// but these are only stable across certain operations: /// /// * **Removing nodes or edges may shift other indices.** Removing a node will /// force the last node to shift its index to take its place. Similarly, /// removing an edge shifts the index of the last edge. /// * Adding nodes or edges keeps indices stable. /// /// The `Ix` parameter is `u32` by default. The goal is that you can ignore this parameter /// completely unless you need a very big graph -- then you can use `usize`. /// /// * The fact that the node and edge indices in the graph each are numbered in compact /// intervals (from 0 to *n* - 1 for *n* nodes) simplifies some graph algorithms. /// /// * You can select graph index integer type after the size of the graph. A smaller /// size may have better performance. /// /// * Using indices allows mutation while traversing the graph, see `Dfs`, /// and `.neighbors(a).detach()`. /// /// * You can create several graphs using the equal node indices but with /// differing weights or differing edges. /// /// * Indices don't allow as much compile time checking as references. /// pub struct Graph { nodes: Vec>, edges: Vec>, ty: PhantomData, } /// A `Graph` with directed edges. /// /// For example, an edge from *1* to *2* is distinct from an edge from *2* to /// *1*. pub type DiGraph = Graph; /// A `Graph` with undirected edges. /// /// For example, an edge between *1* and *2* is equivalent to an edge between /// *2* and *1*. pub type UnGraph = Graph; /// The resulting cloned graph has the same graph indices as `self`. impl Clone for Graph where N: Clone, E: Clone, { fn clone(&self) -> Self { Graph { nodes: self.nodes.clone(), edges: self.edges.clone(), ty: self.ty, } } fn clone_from(&mut self, rhs: &Self) { self.nodes.clone_from(&rhs.nodes); self.edges.clone_from(&rhs.edges); self.ty = rhs.ty; } } impl fmt::Debug for Graph where N: fmt::Debug, E: fmt::Debug, Ty: EdgeType, Ix: IndexType, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let etype = if self.is_directed() { "Directed" } else { "Undirected" }; let mut fmt_struct = f.debug_struct("Graph"); fmt_struct.field("Ty", &etype); fmt_struct.field("node_count", &self.node_count()); fmt_struct.field("edge_count", &self.edge_count()); if self.edge_count() > 0 { fmt_struct.field( "edges", &self .edges .iter() .map(|e| NoPretty((e.source().index(), e.target().index()))) .format(", "), ); } // skip weights if they are ZST! if size_of::() != 0 { fmt_struct.field( "node weights", &DebugMap(|| self.nodes.iter().map(|n| &n.weight).enumerate()), ); } if size_of::() != 0 { fmt_struct.field( "edge weights", &DebugMap(|| self.edges.iter().map(|n| &n.weight).enumerate()), ); } fmt_struct.finish() } } enum Pair { Both(T, T), One(T), None, } use std::cmp::max; /// Get mutable references at index `a` and `b`. fn index_twice(slc: &mut [T], a: usize, b: usize) -> Pair<&mut T> { if max(a, b) >= slc.len() { Pair::None } else if a == b { Pair::One(&mut slc[max(a, b)]) } else { // safe because a, b are in bounds and distinct unsafe { let ptr = slc.as_mut_ptr(); let ar = &mut *ptr.add(a); let br = &mut *ptr.add(b); Pair::Both(ar, br) } } } impl Graph { /// Create a new `Graph` with directed edges. /// /// This is a convenience method. Use `Graph::with_capacity` or `Graph::default` for /// a constructor that is generic in all the type parameters of `Graph`. pub fn new() -> Self { Graph { nodes: Vec::new(), edges: Vec::new(), ty: PhantomData, } } } impl Graph { /// Create a new `Graph` with undirected edges. /// /// This is a convenience method. Use `Graph::with_capacity` or `Graph::default` for /// a constructor that is generic in all the type parameters of `Graph`. pub fn new_undirected() -> Self { Graph { nodes: Vec::new(), edges: Vec::new(), ty: PhantomData, } } } impl Graph where Ty: EdgeType, Ix: IndexType, { /// Create a new `Graph` with estimated capacity. pub fn with_capacity(nodes: usize, edges: usize) -> Self { Graph { nodes: Vec::with_capacity(nodes), edges: Vec::with_capacity(edges), ty: PhantomData, } } /// Return the number of nodes (vertices) in the graph. /// /// Computes in **O(1)** time. pub fn node_count(&self) -> usize { self.nodes.len() } /// Return the number of edges in the graph. /// /// Computes in **O(1)** time. pub fn edge_count(&self) -> usize { self.edges.len() } /// Whether the graph has directed edges or not. #[inline] pub fn is_directed(&self) -> bool { Ty::is_directed() } /// Add a node (also called vertex) with associated data `weight` to the graph. /// /// Computes in **O(1)** time. /// /// Return the index of the new node. /// /// **Panics** if the Graph is at the maximum number of nodes for its index /// type (N/A if usize). pub fn add_node(&mut self, weight: N) -> NodeIndex { let node = Node { weight, next: [EdgeIndex::end(), EdgeIndex::end()], }; let node_idx = NodeIndex::new(self.nodes.len()); // check for max capacity, except if we use usize assert!(::max().index() == !0 || NodeIndex::end() != node_idx); self.nodes.push(node); node_idx } /// Access the weight for node `a`. /// /// If node `a` doesn't exist in the graph, return `None`. /// Also available with indexing syntax: `&graph[a]`. pub fn node_weight(&self, a: NodeIndex) -> Option<&N> { self.nodes.get(a.index()).map(|n| &n.weight) } /// Access the weight for node `a`, mutably. /// /// If node `a` doesn't exist in the graph, return `None`. /// Also available with indexing syntax: `&mut graph[a]`. pub fn node_weight_mut(&mut self, a: NodeIndex) -> Option<&mut N> { self.nodes.get_mut(a.index()).map(|n| &mut n.weight) } /// Add an edge from `a` to `b` to the graph, with its associated /// data `weight`. /// /// Return the index of the new edge. /// /// Computes in **O(1)** time. /// /// **Panics** if any of the nodes don't exist.
/// **Panics** if the Graph is at the maximum number of edges for its index /// type (N/A if usize). /// /// **Note:** `Graph` allows adding parallel (“duplicate”) edges. If you want /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead. pub fn add_edge(&mut self, a: NodeIndex, b: NodeIndex, weight: E) -> EdgeIndex { let edge_idx = EdgeIndex::new(self.edges.len()); assert!(::max().index() == !0 || EdgeIndex::end() != edge_idx); let mut edge = Edge { weight, node: [a, b], next: [EdgeIndex::end(); 2], }; match index_twice(&mut self.nodes, a.index(), b.index()) { Pair::None => panic!("Graph::add_edge: node indices out of bounds"), Pair::One(an) => { edge.next = an.next; an.next[0] = edge_idx; an.next[1] = edge_idx; } Pair::Both(an, bn) => { // a and b are different indices edge.next = [an.next[0], bn.next[1]]; an.next[0] = edge_idx; bn.next[1] = edge_idx; } } self.edges.push(edge); edge_idx } /// Add or update an edge from `a` to `b`. /// If the edge already exists, its weight is updated. /// /// Return the index of the affected edge. /// /// Computes in **O(e')** time, where **e'** is the number of edges /// connected to `a` (and `b`, if the graph edges are undirected). /// /// **Panics** if any of the nodes doesn't exist. pub fn update_edge(&mut self, a: NodeIndex, b: NodeIndex, weight: E) -> EdgeIndex { if let Some(ix) = self.find_edge(a, b) { if let Some(ed) = self.edge_weight_mut(ix) { *ed = weight; return ix; } } self.add_edge(a, b, weight) } /// Access the weight for edge `e`. /// /// If edge `e` doesn't exist in the graph, return `None`. /// Also available with indexing syntax: `&graph[e]`. pub fn edge_weight(&self, e: EdgeIndex) -> Option<&E> { self.edges.get(e.index()).map(|ed| &ed.weight) } /// Access the weight for edge `e`, mutably. /// /// If edge `e` doesn't exist in the graph, return `None`. /// Also available with indexing syntax: `&mut graph[e]`. pub fn edge_weight_mut(&mut self, e: EdgeIndex) -> Option<&mut E> { self.edges.get_mut(e.index()).map(|ed| &mut ed.weight) } /// Access the source and target nodes for `e`. /// /// If edge `e` doesn't exist in the graph, return `None`. pub fn edge_endpoints(&self, e: EdgeIndex) -> Option<(NodeIndex, NodeIndex)> { self.edges .get(e.index()) .map(|ed| (ed.source(), ed.target())) } /// Remove `a` from the graph if it exists, and return its weight. /// If it doesn't exist in the graph, return `None`. /// /// Apart from `a`, this invalidates the last node index in the graph /// (that node will adopt the removed node index). Edge indices are /// invalidated as they would be following the removal of each edge /// with an endpoint in `a`. /// /// Computes in **O(e')** time, where **e'** is the number of affected /// edges, including *n* calls to `.remove_edge()` where *n* is the number /// of edges with an endpoint in `a`, and including the edges with an /// endpoint in the displaced node. pub fn remove_node(&mut self, a: NodeIndex) -> Option { self.nodes.get(a.index())?; for d in &DIRECTIONS { let k = d.index(); // Remove all edges from and to this node. loop { let next = self.nodes[a.index()].next[k]; if next == EdgeIndex::end() { break; } let ret = self.remove_edge(next); debug_assert!(ret.is_some()); let _ = ret; } } // Use swap_remove -- only the swapped-in node is going to change // NodeIndex, so we only have to walk its edges and update them. let node = self.nodes.swap_remove(a.index()); // Find the edge lists of the node that had to relocate. // It may be that no node had to relocate, then we are done already. let swap_edges = match self.nodes.get(a.index()) { None => return Some(node.weight), Some(ed) => ed.next, }; // The swapped element's old index let old_index = NodeIndex::new(self.nodes.len()); let new_index = a; // Adjust the starts of the out edges, and ends of the in edges. for &d in &DIRECTIONS { let k = d.index(); let mut edges = edges_walker_mut(&mut self.edges, swap_edges[k], d); while let Some(curedge) = edges.next_edge() { debug_assert!(curedge.node[k] == old_index); curedge.node[k] = new_index; } } Some(node.weight) } /// For edge `e` with endpoints `edge_node`, replace links to it, /// with links to `edge_next`. fn change_edge_links( &mut self, edge_node: [NodeIndex; 2], e: EdgeIndex, edge_next: [EdgeIndex; 2], ) { for &d in &DIRECTIONS { let k = d.index(); let node = match self.nodes.get_mut(edge_node[k].index()) { Some(r) => r, None => { debug_assert!( false, "Edge's endpoint dir={:?} index={:?} not found", d, edge_node[k] ); return; } }; let fst = node.next[k]; if fst == e { //println!("Updating first edge 0 for node {}, set to {}", edge_node[0], edge_next[0]); node.next[k] = edge_next[k]; } else { let mut edges = edges_walker_mut(&mut self.edges, fst, d); while let Some(curedge) = edges.next_edge() { if curedge.next[k] == e { curedge.next[k] = edge_next[k]; break; // the edge can only be present once in the list. } } } } } /// Remove an edge and return its edge weight, or `None` if it didn't exist. /// /// Apart from `e`, this invalidates the last edge index in the graph /// (that edge will adopt the removed edge index). /// /// Computes in **O(e')** time, where **e'** is the size of four particular edge lists, for /// the vertices of `e` and the vertices of another affected edge. pub fn remove_edge(&mut self, e: EdgeIndex) -> Option { // every edge is part of two lists, // outgoing and incoming edges. // Remove it from both let (edge_node, edge_next) = match self.edges.get(e.index()) { None => return None, Some(x) => (x.node, x.next), }; // Remove the edge from its in and out lists by replacing it with // a link to the next in the list. self.change_edge_links(edge_node, e, edge_next); self.remove_edge_adjust_indices(e) } fn remove_edge_adjust_indices(&mut self, e: EdgeIndex) -> Option { // swap_remove the edge -- only the removed edge // and the edge swapped into place are affected and need updating // indices. let edge = self.edges.swap_remove(e.index()); let swap = match self.edges.get(e.index()) { // no elment needed to be swapped. None => return Some(edge.weight), Some(ed) => ed.node, }; let swapped_e = EdgeIndex::new(self.edges.len()); // Update the edge lists by replacing links to the old index by references to the new // edge index. self.change_edge_links(swap, swapped_e, [e, e]); Some(edge.weight) } /// Return an iterator of all nodes with an edge starting from `a`. /// /// - `Directed`: Outgoing edges from `a`. /// - `Undirected`: All edges from or to `a`. /// /// Produces an empty iterator if the node doesn't exist.
/// Iterator element type is `NodeIndex`. /// /// Use [`.neighbors(a).detach()`][1] to get a neighbor walker that does /// not borrow from the graph. /// /// [1]: struct.Neighbors.html#method.detach pub fn neighbors(&self, a: NodeIndex) -> Neighbors { self.neighbors_directed(a, Outgoing) } /// Return an iterator of all neighbors that have an edge between them and /// `a`, in the specified direction. /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*. /// /// - `Directed`, `Outgoing`: All edges from `a`. /// - `Directed`, `Incoming`: All edges to `a`. /// - `Undirected`: All edges from or to `a`. /// /// Produces an empty iterator if the node doesn't exist.
/// Iterator element type is `NodeIndex`. /// /// For a `Directed` graph, neighbors are listed in reverse order of their /// addition to the graph, so the most recently added edge's neighbor is /// listed first. The order in an `Undirected` graph is arbitrary. /// /// Use [`.neighbors_directed(a, dir).detach()`][1] to get a neighbor walker that does /// not borrow from the graph. /// /// [1]: struct.Neighbors.html#method.detach pub fn neighbors_directed(&self, a: NodeIndex, dir: Direction) -> Neighbors { let mut iter = self.neighbors_undirected(a); if self.is_directed() { let k = dir.index(); iter.next[1 - k] = EdgeIndex::end(); iter.skip_start = NodeIndex::end(); } iter } /// Return an iterator of all neighbors that have an edge between them and /// `a`, in either direction. /// If the graph's edges are undirected, this is equivalent to *.neighbors(a)*. /// /// - `Directed` and `Undirected`: All edges from or to `a`. /// /// Produces an empty iterator if the node doesn't exist.
/// Iterator element type is `NodeIndex`. /// /// Use [`.neighbors_undirected(a).detach()`][1] to get a neighbor walker that does /// not borrow from the graph. /// /// [1]: struct.Neighbors.html#method.detach /// pub fn neighbors_undirected(&self, a: NodeIndex) -> Neighbors { Neighbors { skip_start: a, edges: &self.edges, next: match self.nodes.get(a.index()) { None => [EdgeIndex::end(), EdgeIndex::end()], Some(n) => n.next, }, } } /// Return an iterator of all edges of `a`. /// /// - `Directed`: Outgoing edges from `a`. /// - `Undirected`: All edges connected to `a`. /// /// Produces an empty iterator if the node doesn't exist.
/// Iterator element type is `EdgeReference`. pub fn edges(&self, a: NodeIndex) -> Edges { self.edges_directed(a, Outgoing) } /// Return an iterator of all edges of `a`, in the specified direction. /// /// - `Directed`, `Outgoing`: All edges from `a`. /// - `Directed`, `Incoming`: All edges to `a`. /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each /// edge. /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each /// edge. /// /// Produces an empty iterator if the node `a` doesn't exist.
/// Iterator element type is `EdgeReference`. pub fn edges_directed(&self, a: NodeIndex, dir: Direction) -> Edges { Edges { skip_start: a, edges: &self.edges, direction: dir, next: match self.nodes.get(a.index()) { None => [EdgeIndex::end(), EdgeIndex::end()], Some(n) => n.next, }, ty: PhantomData, } } /// Return an iterator over all the edges connecting `a` and `b`. /// /// - `Directed`: Outgoing edges from `a`. /// - `Undirected`: All edges connected to `a`. /// /// Iterator element type is `EdgeReference`. pub fn edges_connecting( &self, a: NodeIndex, b: NodeIndex, ) -> EdgesConnecting { EdgesConnecting { target_node: b, edges: self.edges_directed(a, Direction::Outgoing), ty: PhantomData, } } /// Lookup if there is an edge from `a` to `b`. /// /// Computes in **O(e')** time, where **e'** is the number of edges /// connected to `a` (and `b`, if the graph edges are undirected). pub fn contains_edge(&self, a: NodeIndex, b: NodeIndex) -> bool { self.find_edge(a, b).is_some() } /// Lookup an edge from `a` to `b`. /// /// Computes in **O(e')** time, where **e'** is the number of edges /// connected to `a` (and `b`, if the graph edges are undirected). pub fn find_edge(&self, a: NodeIndex, b: NodeIndex) -> Option> { if !self.is_directed() { self.find_edge_undirected(a, b).map(|(ix, _)| ix) } else { match self.nodes.get(a.index()) { None => None, Some(node) => self.find_edge_directed_from_node(node, b), } } } fn find_edge_directed_from_node( &self, node: &Node, b: NodeIndex, ) -> Option> { let mut edix = node.next[0]; while let Some(edge) = self.edges.get(edix.index()) { if edge.node[1] == b { return Some(edix); } edix = edge.next[0]; } None } /// Lookup an edge between `a` and `b`, in either direction. /// /// If the graph is undirected, then this is equivalent to `.find_edge()`. /// /// Return the edge index and its directionality, with `Outgoing` meaning /// from `a` to `b` and `Incoming` the reverse, /// or `None` if the edge does not exist. pub fn find_edge_undirected( &self, a: NodeIndex, b: NodeIndex, ) -> Option<(EdgeIndex, Direction)> { match self.nodes.get(a.index()) { None => None, Some(node) => self.find_edge_undirected_from_node(node, b), } } fn find_edge_undirected_from_node( &self, node: &Node, b: NodeIndex, ) -> Option<(EdgeIndex, Direction)> { for &d in &DIRECTIONS { let k = d.index(); let mut edix = node.next[k]; while let Some(edge) = self.edges.get(edix.index()) { if edge.node[1 - k] == b { return Some((edix, d)); } edix = edge.next[k]; } } None } /// Return an iterator over either the nodes without edges to them /// (`Incoming`) or from them (`Outgoing`). /// /// An *internal* node has both incoming and outgoing edges. /// The nodes in `.externals(Incoming)` are the source nodes and /// `.externals(Outgoing)` are the sinks of the graph. /// /// For a graph with undirected edges, both the sinks and the sources are /// just the nodes without edges. /// /// The whole iteration computes in **O(|V|)** time. pub fn externals(&self, dir: Direction) -> Externals { Externals { iter: self.nodes.iter().enumerate(), dir, ty: PhantomData, } } /// Return an iterator over the node indices of the graph. /// /// For example, in a rare case where a graph algorithm were not applicable, /// the following code will iterate through all nodes to find a /// specific index: /// /// ``` /// # use petgraph::Graph; /// # let mut g = Graph::<&str, i32>::new(); /// # g.add_node("book"); /// let index = g.node_indices().find(|i| g[*i] == "book").unwrap(); /// ``` pub fn node_indices(&self) -> NodeIndices { NodeIndices { r: 0..self.node_count(), ty: PhantomData, } } /// Return an iterator yielding mutable access to all node weights. /// /// The order in which weights are yielded matches the order of their /// node indices. pub fn node_weights_mut(&mut self) -> NodeWeightsMut { NodeWeightsMut { nodes: self.nodes.iter_mut(), } } /// Return an iterator yielding immutable access to all node weights. /// /// The order in which weights are yielded matches the order of their /// node indices. pub fn node_weights(&self) -> NodeWeights { NodeWeights { nodes: self.nodes.iter(), } } /// Return an iterator over the edge indices of the graph pub fn edge_indices(&self) -> EdgeIndices { EdgeIndices { r: 0..self.edge_count(), ty: PhantomData, } } /// Create an iterator over all edges, in indexed order. /// /// Iterator element type is `EdgeReference`. pub fn edge_references(&self) -> EdgeReferences { EdgeReferences { iter: self.edges.iter().enumerate(), } } /// Return an iterator yielding immutable access to all edge weights. /// /// The order in which weights are yielded matches the order of their /// edge indices. pub fn edge_weights(&self) -> EdgeWeights { EdgeWeights { edges: self.edges.iter(), } } /// Return an iterator yielding mutable access to all edge weights. /// /// The order in which weights are yielded matches the order of their /// edge indices. pub fn edge_weights_mut(&mut self) -> EdgeWeightsMut { EdgeWeightsMut { edges: self.edges.iter_mut(), } } // Remaining methods are of the more internal flavour, read-only access to // the data structure's internals. /// Access the internal node array. pub fn raw_nodes(&self) -> &[Node] { &self.nodes } /// Access the internal edge array. pub fn raw_edges(&self) -> &[Edge] { &self.edges } #[allow(clippy::type_complexity)] /// Convert the graph into a vector of Nodes and a vector of Edges pub fn into_nodes_edges(self) -> (Vec>, Vec>) { (self.nodes, self.edges) } /// Accessor for data structure internals: the first edge in the given direction. pub fn first_edge(&self, a: NodeIndex, dir: Direction) -> Option> { match self.nodes.get(a.index()) { None => None, Some(node) => { let edix = node.next[dir.index()]; if edix == EdgeIndex::end() { None } else { Some(edix) } } } } /// Accessor for data structure internals: the next edge for the given direction. pub fn next_edge(&self, e: EdgeIndex, dir: Direction) -> Option> { match self.edges.get(e.index()) { None => None, Some(node) => { let edix = node.next[dir.index()]; if edix == EdgeIndex::end() { None } else { Some(edix) } } } } /// Index the `Graph` by two indices, any combination of /// node or edge indices is fine. /// /// **Panics** if the indices are equal or if they are out of bounds. /// /// ``` /// use petgraph::{Graph, Incoming}; /// use petgraph::visit::Dfs; /// /// let mut gr = Graph::new(); /// let a = gr.add_node(0.); /// let b = gr.add_node(0.); /// let c = gr.add_node(0.); /// gr.add_edge(a, b, 3.); /// gr.add_edge(b, c, 2.); /// gr.add_edge(c, b, 1.); /// /// // walk the graph and sum incoming edges into the node weight /// let mut dfs = Dfs::new(&gr, a); /// while let Some(node) = dfs.next(&gr) { /// // use a walker -- a detached neighbors iterator /// let mut edges = gr.neighbors_directed(node, Incoming).detach(); /// while let Some(edge) = edges.next_edge(&gr) { /// let (nw, ew) = gr.index_twice_mut(node, edge); /// *nw += *ew; /// } /// } /// /// // check the result /// assert_eq!(gr[a], 0.); /// assert_eq!(gr[b], 4.); /// assert_eq!(gr[c], 2.); /// ``` pub fn index_twice_mut( &mut self, i: T, j: U, ) -> ( &mut >::Output, &mut >::Output, ) where Self: IndexMut + IndexMut, T: GraphIndex, U: GraphIndex, { assert!(T::is_node_index() != U::is_node_index() || i.index() != j.index()); // Allow two mutable indexes here -- they are nonoverlapping unsafe { let self_mut = self as *mut _; ( >::index_mut(&mut *self_mut, i), >::index_mut(&mut *self_mut, j), ) } } /// Reverse the direction of all edges pub fn reverse(&mut self) { // swap edge endpoints, // edge incoming / outgoing lists, // node incoming / outgoing lists for edge in &mut self.edges { edge.node.swap(0, 1); edge.next.swap(0, 1); } for node in &mut self.nodes { node.next.swap(0, 1); } } /// Remove all nodes and edges pub fn clear(&mut self) { self.nodes.clear(); self.edges.clear(); } /// Remove all edges pub fn clear_edges(&mut self) { self.edges.clear(); for node in &mut self.nodes { node.next = [EdgeIndex::end(), EdgeIndex::end()]; } } /// Return the current node and edge capacity of the graph. pub fn capacity(&self) -> (usize, usize) { (self.nodes.capacity(), self.edges.capacity()) } /// Reserves capacity for at least `additional` more nodes to be inserted in /// the graph. Graph may reserve more space to avoid frequent reallocations. /// /// **Panics** if the new capacity overflows `usize`. pub fn reserve_nodes(&mut self, additional: usize) { self.nodes.reserve(additional); } /// Reserves capacity for at least `additional` more edges to be inserted in /// the graph. Graph may reserve more space to avoid frequent reallocations. /// /// **Panics** if the new capacity overflows `usize`. pub fn reserve_edges(&mut self, additional: usize) { self.edges.reserve(additional); } /// Reserves the minimum capacity for exactly `additional` more nodes to be /// inserted in the graph. Does nothing if the capacity is already /// sufficient. /// /// Prefer `reserve_nodes` if future insertions are expected. /// /// **Panics** if the new capacity overflows `usize`. pub fn reserve_exact_nodes(&mut self, additional: usize) { self.nodes.reserve_exact(additional); } /// Reserves the minimum capacity for exactly `additional` more edges to be /// inserted in the graph. /// Does nothing if the capacity is already sufficient. /// /// Prefer `reserve_edges` if future insertions are expected. /// /// **Panics** if the new capacity overflows `usize`. pub fn reserve_exact_edges(&mut self, additional: usize) { self.edges.reserve_exact(additional); } /// Shrinks the capacity of the underlying nodes collection as much as possible. pub fn shrink_to_fit_nodes(&mut self) { self.nodes.shrink_to_fit(); } /// Shrinks the capacity of the underlying edges collection as much as possible. pub fn shrink_to_fit_edges(&mut self) { self.edges.shrink_to_fit(); } /// Shrinks the capacity of the graph as much as possible. pub fn shrink_to_fit(&mut self) { self.nodes.shrink_to_fit(); self.edges.shrink_to_fit(); } /// Keep all nodes that return `true` from the `visit` closure, /// remove the others. /// /// `visit` is provided a proxy reference to the graph, so that /// the graph can be walked and associated data modified. /// /// The order nodes are visited is not specified. pub fn retain_nodes(&mut self, mut visit: F) where F: FnMut(Frozen, NodeIndex) -> bool, { for index in self.node_indices().rev() { if !visit(Frozen(self), index) { let ret = self.remove_node(index); debug_assert!(ret.is_some()); let _ = ret; } } } /// Keep all edges that return `true` from the `visit` closure, /// remove the others. /// /// `visit` is provided a proxy reference to the graph, so that /// the graph can be walked and associated data modified. /// /// The order edges are visited is not specified. pub fn retain_edges(&mut self, mut visit: F) where F: FnMut(Frozen, EdgeIndex) -> bool, { for index in self.edge_indices().rev() { if !visit(Frozen(self), index) { let ret = self.remove_edge(index); debug_assert!(ret.is_some()); let _ = ret; } } } /// Create a new `Graph` from an iterable of edges. /// /// Node weights `N` are set to default values. /// Edge weights `E` may either be specified in the list, /// or they are filled with default values. /// /// Nodes are inserted automatically to match the edges. /// /// ``` /// use petgraph::Graph; /// /// let gr = Graph::<(), i32>::from_edges(&[ /// (0, 1), (0, 2), (0, 3), /// (1, 2), (1, 3), /// (2, 3), /// ]); /// ``` pub fn from_edges(iterable: I) -> Self where I: IntoIterator, I::Item: IntoWeightedEdge, >::NodeId: Into>, N: Default, { let mut g = Self::with_capacity(0, 0); g.extend_with_edges(iterable); g } /// Extend the graph from an iterable of edges. /// /// Node weights `N` are set to default values. /// Edge weights `E` may either be specified in the list, /// or they are filled with default values. /// /// Nodes are inserted automatically to match the edges. pub fn extend_with_edges(&mut self, iterable: I) where I: IntoIterator, I::Item: IntoWeightedEdge, >::NodeId: Into>, N: Default, { let iter = iterable.into_iter(); let (low, _) = iter.size_hint(); self.edges.reserve(low); for elt in iter { let (source, target, weight) = elt.into_weighted_edge(); let (source, target) = (source.into(), target.into()); let nx = cmp::max(source, target); while nx.index() >= self.node_count() { self.add_node(N::default()); } self.add_edge(source, target, weight); } } /// Create a new `Graph` by mapping node and /// edge weights to new values. /// /// The resulting graph has the same structure and the same /// graph indices as `self`. pub fn map<'a, F, G, N2, E2>( &'a self, mut node_map: F, mut edge_map: G, ) -> Graph where F: FnMut(NodeIndex, &'a N) -> N2, G: FnMut(EdgeIndex, &'a E) -> E2, { let mut g = Graph::with_capacity(self.node_count(), self.edge_count()); g.nodes.extend(enumerate(&self.nodes).map(|(i, node)| Node { weight: node_map(NodeIndex::new(i), &node.weight), next: node.next, })); g.edges.extend(enumerate(&self.edges).map(|(i, edge)| Edge { weight: edge_map(EdgeIndex::new(i), &edge.weight), next: edge.next, node: edge.node, })); g } /// Create a new `Graph` by mapping nodes and edges. /// A node or edge may be mapped to `None` to exclude it from /// the resulting graph. /// /// Nodes are mapped first with the `node_map` closure, then /// `edge_map` is called for the edges that have not had any endpoint /// removed. /// /// The resulting graph has the structure of a subgraph of the original graph. /// If no nodes are removed, the resulting graph has compatible node /// indices; if neither nodes nor edges are removed, the result has /// the same graph indices as `self`. pub fn filter_map<'a, F, G, N2, E2>( &'a self, mut node_map: F, mut edge_map: G, ) -> Graph where F: FnMut(NodeIndex, &'a N) -> Option, G: FnMut(EdgeIndex, &'a E) -> Option, { let mut g = Graph::with_capacity(0, 0); // mapping from old node index to new node index, end represents removed. let mut node_index_map = vec![NodeIndex::end(); self.node_count()]; for (i, node) in enumerate(&self.nodes) { if let Some(nw) = node_map(NodeIndex::new(i), &node.weight) { node_index_map[i] = g.add_node(nw); } } for (i, edge) in enumerate(&self.edges) { // skip edge if any endpoint was removed let source = node_index_map[edge.source().index()]; let target = node_index_map[edge.target().index()]; if source != NodeIndex::end() && target != NodeIndex::end() { if let Some(ew) = edge_map(EdgeIndex::new(i), &edge.weight) { g.add_edge(source, target, ew); } } } g } /// Convert the graph into either undirected or directed. No edge adjustments /// are done, so you may want to go over the result to remove or add edges. /// /// Computes in **O(1)** time. pub fn into_edge_type(self) -> Graph where NewTy: EdgeType, { Graph { nodes: self.nodes, edges: self.edges, ty: PhantomData, } } // // internal methods // #[cfg(feature = "serde-1")] /// Fix up node and edge links after deserialization fn link_edges(&mut self) -> Result<(), NodeIndex> { for (edge_index, edge) in enumerate(&mut self.edges) { let a = edge.source(); let b = edge.target(); let edge_idx = EdgeIndex::new(edge_index); match index_twice(&mut self.nodes, a.index(), b.index()) { Pair::None => return Err(if a > b { a } else { b }), Pair::One(an) => { edge.next = an.next; an.next[0] = edge_idx; an.next[1] = edge_idx; } Pair::Both(an, bn) => { // a and b are different indices edge.next = [an.next[0], bn.next[1]]; an.next[0] = edge_idx; bn.next[1] = edge_idx; } } } Ok(()) } } /// An iterator over either the nodes without edges to them or from them. #[derive(Debug, Clone)] pub struct Externals<'a, N: 'a, Ty, Ix: IndexType = DefaultIx> { iter: iter::Enumerate>>, dir: Direction, ty: PhantomData, } impl<'a, N: 'a, Ty, Ix> Iterator for Externals<'a, N, Ty, Ix> where Ty: EdgeType, Ix: IndexType, { type Item = NodeIndex; fn next(&mut self) -> Option> { let k = self.dir.index(); loop { match self.iter.next() { None => return None, Some((index, node)) => { if node.next[k] == EdgeIndex::end() && (Ty::is_directed() || node.next[1 - k] == EdgeIndex::end()) { return Some(NodeIndex::new(index)); } else { continue; } } } } } fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) } } /// Iterator over the neighbors of a node. /// /// Iterator element type is `NodeIndex`. /// /// Created with [`.neighbors()`][1], [`.neighbors_directed()`][2] or /// [`.neighbors_undirected()`][3]. /// /// [1]: struct.Graph.html#method.neighbors /// [2]: struct.Graph.html#method.neighbors_directed /// [3]: struct.Graph.html#method.neighbors_undirected #[derive(Debug)] pub struct Neighbors<'a, E: 'a, Ix: 'a = DefaultIx> { /// starting node to skip over skip_start: NodeIndex, edges: &'a [Edge], next: [EdgeIndex; 2], } impl<'a, E, Ix> Iterator for Neighbors<'a, E, Ix> where Ix: IndexType, { type Item = NodeIndex; fn next(&mut self) -> Option> { // First any outgoing edges match self.edges.get(self.next[0].index()) { None => {} Some(edge) => { self.next[0] = edge.next[0]; return Some(edge.node[1]); } } // Then incoming edges // For an "undirected" iterator (traverse both incoming // and outgoing edge lists), make sure we don't double // count selfloops by skipping them in the incoming list. while let Some(edge) = self.edges.get(self.next[1].index()) { self.next[1] = edge.next[1]; if edge.node[0] != self.skip_start { return Some(edge.node[0]); } } None } } impl<'a, E, Ix> Clone for Neighbors<'a, E, Ix> where Ix: IndexType, { clone_fields!(Neighbors, skip_start, edges, next,); } impl<'a, E, Ix> Neighbors<'a, E, Ix> where Ix: IndexType, { /// Return a “walker” object that can be used to step through the /// neighbors and edges from the origin node. /// /// Note: The walker does not borrow from the graph, this is to allow mixing /// edge walking with mutating the graph's weights. pub fn detach(&self) -> WalkNeighbors { WalkNeighbors { skip_start: self.skip_start, next: self.next, } } } struct EdgesWalkerMut<'a, E: 'a, Ix: IndexType = DefaultIx> { edges: &'a mut [Edge], next: EdgeIndex, dir: Direction, } fn edges_walker_mut( edges: &mut [Edge], next: EdgeIndex, dir: Direction, ) -> EdgesWalkerMut where Ix: IndexType, { EdgesWalkerMut { edges, next, dir } } impl<'a, E, Ix> EdgesWalkerMut<'a, E, Ix> where Ix: IndexType, { fn next_edge(&mut self) -> Option<&mut Edge> { self.next().map(|t| t.1) } fn next(&mut self) -> Option<(EdgeIndex, &mut Edge)> { let this_index = self.next; let k = self.dir.index(); match self.edges.get_mut(self.next.index()) { None => None, Some(edge) => { self.next = edge.next[k]; Some((this_index, edge)) } } } } impl<'a, N, E, Ty, Ix> visit::IntoEdges for &'a Graph where Ty: EdgeType, Ix: IndexType, { type Edges = Edges<'a, E, Ty, Ix>; fn edges(self, a: Self::NodeId) -> Self::Edges { self.edges(a) } } impl<'a, N, E, Ty, Ix> visit::IntoEdgesDirected for &'a Graph where Ty: EdgeType, Ix: IndexType, { type EdgesDirected = Edges<'a, E, Ty, Ix>; fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::EdgesDirected { self.edges_directed(a, dir) } } /// Iterator over the edges of from or to a node #[derive(Debug)] pub struct Edges<'a, E: 'a, Ty, Ix: 'a = DefaultIx> where Ty: EdgeType, Ix: IndexType, { /// starting node to skip over skip_start: NodeIndex, edges: &'a [Edge], /// Next edge to visit. next: [EdgeIndex; 2], /// For directed graphs: the direction to iterate in /// For undirected graphs: the direction of edges direction: Direction, ty: PhantomData, } impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix> where Ty: EdgeType, Ix: IndexType, { type Item = EdgeReference<'a, E, Ix>; fn next(&mut self) -> Option { // type direction | iterate over reverse // | // Directed Outgoing | outgoing no // Directed Incoming | incoming no // Undirected Outgoing | both incoming // Undirected Incoming | both outgoing // For iterate_over, "both" is represented as None. // For reverse, "no" is represented as None. let (iterate_over, reverse) = if Ty::is_directed() { (Some(self.direction), None) } else { (None, Some(self.direction.opposite())) }; if iterate_over.unwrap_or(Outgoing) == Outgoing { let i = self.next[0].index(); if let Some(Edge { node, weight, next }) = self.edges.get(i) { self.next[0] = next[0]; return Some(EdgeReference { index: edge_index(i), node: if reverse == Some(Outgoing) { swap_pair(*node) } else { *node }, weight, }); } } if iterate_over.unwrap_or(Incoming) == Incoming { while let Some(Edge { node, weight, next }) = self.edges.get(self.next[1].index()) { let edge_index = self.next[1]; self.next[1] = next[1]; // In any of the "both" situations, self-loops would be iterated over twice. // Skip them here. if iterate_over.is_none() && node[0] == self.skip_start { continue; } return Some(EdgeReference { index: edge_index, node: if reverse == Some(Incoming) { swap_pair(*node) } else { *node }, weight, }); } } None } } /// Iterator over the multiple directed edges connecting a source node to a target node #[derive(Debug, Clone)] pub struct EdgesConnecting<'a, E: 'a, Ty, Ix: 'a = DefaultIx> where Ty: EdgeType, Ix: IndexType, { target_node: NodeIndex, edges: Edges<'a, E, Ty, Ix>, ty: PhantomData, } impl<'a, E, Ty, Ix> Iterator for EdgesConnecting<'a, E, Ty, Ix> where Ty: EdgeType, Ix: IndexType, { type Item = EdgeReference<'a, E, Ix>; fn next(&mut self) -> Option> { let target_node = self.target_node; self.edges .by_ref() .find(|&edge| edge.node[1] == target_node) } fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.edges.size_hint(); (0, upper) } } fn swap_pair(mut x: [T; 2]) -> [T; 2] { x.swap(0, 1); x } impl<'a, E, Ty, Ix> Clone for Edges<'a, E, Ty, Ix> where Ix: IndexType, Ty: EdgeType, { fn clone(&self) -> Self { Edges { skip_start: self.skip_start, edges: self.edges, next: self.next, direction: self.direction, ty: self.ty, } } } /// Iterator yielding immutable access to all node weights. pub struct NodeWeights<'a, N: 'a, Ix: IndexType = DefaultIx> { nodes: ::std::slice::Iter<'a, Node>, } impl<'a, N, Ix> Iterator for NodeWeights<'a, N, Ix> where Ix: IndexType, { type Item = &'a N; fn next(&mut self) -> Option<&'a N> { self.nodes.next().map(|node| &node.weight) } fn size_hint(&self) -> (usize, Option) { self.nodes.size_hint() } } /// Iterator yielding mutable access to all node weights. #[derive(Debug)] pub struct NodeWeightsMut<'a, N: 'a, Ix: IndexType = DefaultIx> { nodes: ::std::slice::IterMut<'a, Node>, // TODO: change type to something that implements Clone? } impl<'a, N, Ix> Iterator for NodeWeightsMut<'a, N, Ix> where Ix: IndexType, { type Item = &'a mut N; fn next(&mut self) -> Option<&'a mut N> { self.nodes.next().map(|node| &mut node.weight) } fn size_hint(&self) -> (usize, Option) { self.nodes.size_hint() } } /// Iterator yielding immutable access to all edge weights. pub struct EdgeWeights<'a, E: 'a, Ix: IndexType = DefaultIx> { edges: ::std::slice::Iter<'a, Edge>, } impl<'a, E, Ix> Iterator for EdgeWeights<'a, E, Ix> where Ix: IndexType, { type Item = &'a E; fn next(&mut self) -> Option<&'a E> { self.edges.next().map(|edge| &edge.weight) } fn size_hint(&self) -> (usize, Option) { self.edges.size_hint() } } /// Iterator yielding mutable access to all edge weights. #[derive(Debug)] pub struct EdgeWeightsMut<'a, E: 'a, Ix: IndexType = DefaultIx> { edges: ::std::slice::IterMut<'a, Edge>, // TODO: change type to something that implements Clone? } impl<'a, E, Ix> Iterator for EdgeWeightsMut<'a, E, Ix> where Ix: IndexType, { type Item = &'a mut E; fn next(&mut self) -> Option<&'a mut E> { self.edges.next().map(|edge| &mut edge.weight) } fn size_hint(&self) -> (usize, Option) { self.edges.size_hint() } } /// Index the `Graph` by `NodeIndex` to access node weights. /// /// **Panics** if the node doesn't exist. impl Index> for Graph where Ty: EdgeType, Ix: IndexType, { type Output = N; fn index(&self, index: NodeIndex) -> &N { &self.nodes[index.index()].weight } } /// Index the `Graph` by `NodeIndex` to access node weights. /// /// **Panics** if the node doesn't exist. impl IndexMut> for Graph where Ty: EdgeType, Ix: IndexType, { fn index_mut(&mut self, index: NodeIndex) -> &mut N { &mut self.nodes[index.index()].weight } } /// Index the `Graph` by `EdgeIndex` to access edge weights. /// /// **Panics** if the edge doesn't exist. impl Index> for Graph where Ty: EdgeType, Ix: IndexType, { type Output = E; fn index(&self, index: EdgeIndex) -> &E { &self.edges[index.index()].weight } } /// Index the `Graph` by `EdgeIndex` to access edge weights. /// /// **Panics** if the edge doesn't exist. impl IndexMut> for Graph where Ty: EdgeType, Ix: IndexType, { fn index_mut(&mut self, index: EdgeIndex) -> &mut E { &mut self.edges[index.index()].weight } } /// Create a new empty `Graph`. impl Default for Graph where Ty: EdgeType, Ix: IndexType, { fn default() -> Self { Self::with_capacity(0, 0) } } /// A `GraphIndex` is a node or edge index. pub trait GraphIndex: Copy { #[doc(hidden)] fn index(&self) -> usize; #[doc(hidden)] fn is_node_index() -> bool; } impl GraphIndex for NodeIndex { #[inline] #[doc(hidden)] fn index(&self) -> usize { NodeIndex::index(*self) } #[inline] #[doc(hidden)] fn is_node_index() -> bool { true } } impl GraphIndex for EdgeIndex { #[inline] #[doc(hidden)] fn index(&self) -> usize { EdgeIndex::index(*self) } #[inline] #[doc(hidden)] fn is_node_index() -> bool { false } } /// A “walker” object that can be used to step through the edge list of a node. /// /// Created with [`.detach()`](struct.Neighbors.html#method.detach). /// /// The walker does not borrow from the graph, so it lets you step through /// neighbors or incident edges while also mutating graph weights, as /// in the following example: /// /// ``` /// use petgraph::{Graph, Incoming}; /// use petgraph::visit::Dfs; /// /// let mut gr = Graph::new(); /// let a = gr.add_node(0.); /// let b = gr.add_node(0.); /// let c = gr.add_node(0.); /// gr.add_edge(a, b, 3.); /// gr.add_edge(b, c, 2.); /// gr.add_edge(c, b, 1.); /// /// // step through the graph and sum incoming edges into the node weight /// let mut dfs = Dfs::new(&gr, a); /// while let Some(node) = dfs.next(&gr) { /// // use a detached neighbors walker /// let mut edges = gr.neighbors_directed(node, Incoming).detach(); /// while let Some(edge) = edges.next_edge(&gr) { /// gr[node] += gr[edge]; /// } /// } /// /// // check the result /// assert_eq!(gr[a], 0.); /// assert_eq!(gr[b], 4.); /// assert_eq!(gr[c], 2.); /// ``` pub struct WalkNeighbors { skip_start: NodeIndex, next: [EdgeIndex; 2], } impl Clone for WalkNeighbors where Ix: IndexType, { fn clone(&self) -> Self { WalkNeighbors { skip_start: self.skip_start, next: self.next, } } } impl WalkNeighbors { /// Step to the next edge and its endpoint node in the walk for graph `g`. /// /// The next node indices are always the others than the starting point /// where the `WalkNeighbors` value was created. /// For an `Outgoing` walk, the target nodes, /// for an `Incoming` walk, the source nodes of the edge. pub fn next( &mut self, g: &Graph, ) -> Option<(EdgeIndex, NodeIndex)> { // First any outgoing edges match g.edges.get(self.next[0].index()) { None => {} Some(edge) => { let ed = self.next[0]; self.next[0] = edge.next[0]; return Some((ed, edge.node[1])); } } // Then incoming edges // For an "undirected" iterator (traverse both incoming // and outgoing edge lists), make sure we don't double // count selfloops by skipping them in the incoming list. while let Some(edge) = g.edges.get(self.next[1].index()) { let ed = self.next[1]; self.next[1] = edge.next[1]; if edge.node[0] != self.skip_start { return Some((ed, edge.node[0])); } } None } pub fn next_node( &mut self, g: &Graph, ) -> Option> { self.next(g).map(|t| t.1) } pub fn next_edge( &mut self, g: &Graph, ) -> Option> { self.next(g).map(|t| t.0) } } /// Iterator over the node indices of a graph. #[derive(Clone, Debug)] pub struct NodeIndices { r: Range, ty: PhantomData Ix>, } impl Iterator for NodeIndices { type Item = NodeIndex; fn next(&mut self) -> Option { self.r.next().map(node_index) } fn size_hint(&self) -> (usize, Option) { self.r.size_hint() } } impl DoubleEndedIterator for NodeIndices { fn next_back(&mut self) -> Option { self.r.next_back().map(node_index) } } impl ExactSizeIterator for NodeIndices {} /// Iterator over the edge indices of a graph. #[derive(Clone, Debug)] pub struct EdgeIndices { r: Range, ty: PhantomData Ix>, } impl Iterator for EdgeIndices { type Item = EdgeIndex; fn next(&mut self) -> Option { self.r.next().map(edge_index) } fn size_hint(&self) -> (usize, Option) { self.r.size_hint() } } impl DoubleEndedIterator for EdgeIndices { fn next_back(&mut self) -> Option { self.r.next_back().map(edge_index) } } impl ExactSizeIterator for EdgeIndices {} /// Reference to a `Graph` edge. #[derive(Debug)] pub struct EdgeReference<'a, E: 'a, Ix = DefaultIx> { index: EdgeIndex, node: [NodeIndex; 2], weight: &'a E, } impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> { fn clone(&self) -> Self { *self } } impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {} impl<'a, E, Ix: IndexType> PartialEq for EdgeReference<'a, E, Ix> where E: PartialEq, { fn eq(&self, rhs: &Self) -> bool { self.index == rhs.index && self.weight == rhs.weight } } impl visit::GraphBase for Graph where Ix: IndexType, { type NodeId = NodeIndex; type EdgeId = EdgeIndex; } impl visit::Visitable for Graph where Ty: EdgeType, Ix: IndexType, { type Map = FixedBitSet; fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) } fn reset_map(&self, map: &mut Self::Map) { map.clear(); map.grow(self.node_count()); } } impl visit::GraphProp for Graph where Ty: EdgeType, Ix: IndexType, { type EdgeType = Ty; } impl<'a, N, E: 'a, Ty, Ix> visit::IntoNodeIdentifiers for &'a Graph where Ty: EdgeType, Ix: IndexType, { type NodeIdentifiers = NodeIndices; fn node_identifiers(self) -> NodeIndices { Graph::node_indices(self) } } impl visit::NodeCount for Graph where Ty: EdgeType, Ix: IndexType, { fn node_count(&self) -> usize { self.node_count() } } impl visit::NodeIndexable for Graph where Ty: EdgeType, Ix: IndexType, { #[inline] fn node_bound(&self) -> usize { self.node_count() } #[inline] fn to_index(&self, ix: NodeIndex) -> usize { ix.index() } #[inline] fn from_index(&self, ix: usize) -> Self::NodeId { NodeIndex::new(ix) } } impl visit::NodeCompactIndexable for Graph where Ty: EdgeType, Ix: IndexType, { } impl<'a, N, E: 'a, Ty, Ix> visit::IntoNeighbors for &'a Graph where Ty: EdgeType, Ix: IndexType, { type Neighbors = Neighbors<'a, E, Ix>; fn neighbors(self, n: NodeIndex) -> Neighbors<'a, E, Ix> { Graph::neighbors(self, n) } } impl<'a, N, E: 'a, Ty, Ix> visit::IntoNeighborsDirected for &'a Graph where Ty: EdgeType, Ix: IndexType, { type NeighborsDirected = Neighbors<'a, E, Ix>; fn neighbors_directed(self, n: NodeIndex, d: Direction) -> Neighbors<'a, E, Ix> { Graph::neighbors_directed(self, n, d) } } impl<'a, N: 'a, E: 'a, Ty, Ix> visit::IntoEdgeReferences for &'a Graph where Ty: EdgeType, Ix: IndexType, { type EdgeRef = EdgeReference<'a, E, Ix>; type EdgeReferences = EdgeReferences<'a, E, Ix>; fn edge_references(self) -> Self::EdgeReferences { (*self).edge_references() } } impl visit::EdgeCount for Graph where Ty: EdgeType, Ix: IndexType, { #[inline] fn edge_count(&self) -> usize { self.edge_count() } } impl<'a, N, E, Ty, Ix> visit::IntoNodeReferences for &'a Graph where Ty: EdgeType, Ix: IndexType, { type NodeRef = (NodeIndex, &'a N); type NodeReferences = NodeReferences<'a, N, Ix>; fn node_references(self) -> Self::NodeReferences { NodeReferences { iter: self.nodes.iter().enumerate(), } } } /// Iterator over all nodes of a graph. #[derive(Debug, Clone)] pub struct NodeReferences<'a, N: 'a, Ix: IndexType = DefaultIx> { iter: iter::Enumerate>>, } impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix> where Ix: IndexType, { type Item = (NodeIndex, &'a N); fn next(&mut self) -> Option { self.iter .next() .map(|(i, node)| (node_index(i), &node.weight)) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, N, Ix> DoubleEndedIterator for NodeReferences<'a, N, Ix> where Ix: IndexType, { fn next_back(&mut self) -> Option { self.iter .next_back() .map(|(i, node)| (node_index(i), &node.weight)) } } impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix> where Ix: IndexType {} impl<'a, Ix, E> EdgeReference<'a, E, Ix> where Ix: IndexType, { /// Access the edge’s weight. /// /// **NOTE** that this method offers a longer lifetime /// than the trait (unfortunately they don't match yet). pub fn weight(&self) -> &'a E { self.weight } } impl<'a, Ix, E> visit::EdgeRef for EdgeReference<'a, E, Ix> where Ix: IndexType, { type NodeId = NodeIndex; type EdgeId = EdgeIndex; type Weight = E; fn source(&self) -> Self::NodeId { self.node[0] } fn target(&self) -> Self::NodeId { self.node[1] } fn weight(&self) -> &E { self.weight } fn id(&self) -> Self::EdgeId { self.index } } /// Iterator over all edges of a graph. #[derive(Debug, Clone)] pub struct EdgeReferences<'a, E: 'a, Ix: IndexType = DefaultIx> { iter: iter::Enumerate>>, } impl<'a, E, Ix> Iterator for EdgeReferences<'a, E, Ix> where Ix: IndexType, { type Item = EdgeReference<'a, E, Ix>; fn next(&mut self) -> Option { self.iter.next().map(|(i, edge)| EdgeReference { index: edge_index(i), node: edge.node, weight: &edge.weight, }) } fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, E, Ix> DoubleEndedIterator for EdgeReferences<'a, E, Ix> where Ix: IndexType, { fn next_back(&mut self) -> Option { self.iter.next_back().map(|(i, edge)| EdgeReference { index: edge_index(i), node: edge.node, weight: &edge.weight, }) } } impl<'a, E, Ix> ExactSizeIterator for EdgeReferences<'a, E, Ix> where Ix: IndexType {} impl visit::EdgeIndexable for Graph where Ty: EdgeType, Ix: IndexType, { fn edge_bound(&self) -> usize { self.edge_count() } fn to_index(&self, ix: EdgeIndex) -> usize { ix.index() } fn from_index(&self, ix: usize) -> Self::EdgeId { EdgeIndex::new(ix) } } mod frozen; #[cfg(feature = "stable_graph")] pub mod stable_graph; /// `Frozen` is a graph wrapper. /// /// The `Frozen` only allows shared access (read-only) to the /// underlying graph `G`, but it allows mutable access to its /// node and edge weights. /// /// This is used to ensure immutability of the graph's structure /// while permitting weights to be both read and written. /// /// See indexing implementations and the traits `Data` and `DataMap` /// for read-write access to the graph's weights. pub struct Frozen<'a, G: 'a>(&'a mut G);