1 //! Graph traits and graph traversals.
3 //! ### The `Into-` Traits
5 //! Graph traits like [`IntoNeighbors`][in] create iterators and use the same
6 //! pattern that `IntoIterator` does: the trait takes a reference to a graph,
7 //! and produces an iterator. These traits are quite composable, but with the
8 //! limitation that they only use shared references to graphs.
10 //! ### Graph Traversal
12 //! [`Dfs`](struct.Dfs.html), [`Bfs`][bfs], [`DfsPostOrder`][dfspo] and
13 //! [`Topo`][topo] are basic visitors and they use “walker” methods: the
14 //! visitors don't hold the graph as borrowed during traversal, only for the
15 //! `.next()` call on the walker. They can be converted to iterators
16 //! through the [`Walker`][w] trait.
18 //! There is also the callback based traversal [`depth_first_search`][dfs].
20 //! [bfs]: struct.Bfs.html
21 //! [dfspo]: struct.DfsPostOrder.html
22 //! [topo]: struct.Topo.html
23 //! [dfs]: fn.depth_first_search.html
24 //! [w]: trait.Walker.html
26 //! ### Other Graph Traits
28 //! The traits are rather loosely coupled at the moment (which is intentional,
29 //! but will develop a bit), and there are traits missing that could be added.
31 //! Not much is needed to be able to use the visitors on a graph. A graph
32 //! needs to define [`GraphBase`][gb], [`IntoNeighbors`][in] and
33 //! [`Visitable`][vis] as a minimum.
35 //! [gb]: trait.GraphBase.html
36 //! [in]: trait.IntoNeighbors.html
37 //! [vis]: trait.Visitable.html
40 // filter, reversed have their `mod` lines at the end,
41 // so that they can use the trait template macros
42 pub use self::filter
::*;
43 pub use self::reversed
::*;
50 pub use self::dfsvisit
::*;
51 pub use self::traversal
::*;
53 use fixedbitset
::FixedBitSet
;
54 use std
::collections
::HashSet
;
55 use std
::hash
::{BuildHasher, Hash}
;
57 use super::{graph, EdgeType}
;
58 use crate::graph
::NodeIndex
;
59 #[cfg(feature = "graphmap")]
60 use crate::prelude
::GraphMap
;
61 #[cfg(feature = "stable_graph")]
62 use crate::prelude
::StableGraph
;
63 use crate::prelude
::{Direction, Graph}
;
65 use crate::graph
::Frozen
;
66 use crate::graph
::IndexType
;
67 #[cfg(feature = "stable_graph")]
68 use crate::stable_graph
;
70 #[cfg(feature = "graphmap")]
71 use crate::graphmap
::{self, NodeTrait}
;
74 /// Base graph trait: defines the associated node identifier and
75 /// edge identifier types.
77 // FIXME: We can drop this escape/nodelegate stuff in Rust 1.18
82 type EdgeId
: Copy
+ PartialEq
;
84 type NodeId
: Copy
+ PartialEq
;
88 GraphBase
! {delegate_impl []}
89 GraphBase
! {delegate_impl [['a, G], G, &'a mut G, deref]}
91 /// A copyable reference to a graph.
92 pub trait GraphRef
: Copy
+ GraphBase {}
94 impl<'a
, G
> GraphRef
for &'a G
where G
: GraphBase {}
96 impl<'a
, G
> GraphBase
for Frozen
<'a
, G
>
100 type NodeId
= G
::NodeId
;
101 type EdgeId
= G
::EdgeId
;
104 #[cfg(feature = "stable_graph")]
105 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNeighbors
for &'a StableGraph
<N
, E
, Ty
, Ix
>
110 type Neighbors
= stable_graph
::Neighbors
<'a
, E
, Ix
>;
111 fn neighbors(self, n
: Self::NodeId
) -> Self::Neighbors
{
116 #[cfg(feature = "graphmap")]
117 impl<'a
, N
: 'a
, E
, Ty
> IntoNeighbors
for &'a GraphMap
<N
, E
, Ty
>
119 N
: Copy
+ Ord
+ Hash
,
122 type Neighbors
= graphmap
::Neighbors
<'a
, N
, Ty
>;
123 fn neighbors(self, n
: Self::NodeId
) -> Self::Neighbors
{
129 /// Access to the neighbors of each node
131 /// The neighbors are, depending on the graph’s edge type:
133 /// - `Directed`: All targets of edges from `a`.
134 /// - `Undirected`: All other endpoints of edges connected to `a`.
135 pub trait IntoNeighbors
: GraphRef
{
137 type Neighbors
: Iterator
<Item
=Self::NodeId
>;
139 /// Return an iterator of the neighbors of node `a`.
140 fn neighbors(self: Self, a
: Self::NodeId
) -> Self::Neighbors
;
144 IntoNeighbors
! {delegate_impl []}
147 /// Access to the neighbors of each node, through incoming or outgoing edges.
149 /// Depending on the graph’s edge type, the neighbors of a given directionality
152 /// - `Directed`, `Outgoing`: All targets of edges from `a`.
153 /// - `Directed`, `Incoming`: All sources of edges to `a`.
154 /// - `Undirected`: All other endpoints of edges connected to `a`.
155 pub trait IntoNeighborsDirected
: IntoNeighbors
{
157 type NeighborsDirected
: Iterator
<Item
=Self::NodeId
>;
159 fn neighbors_directed(self, n
: Self::NodeId
, d
: Direction
)
160 -> Self::NeighborsDirected
;
164 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNeighbors
for &'a Graph
<N
, E
, Ty
, Ix
>
169 type Neighbors
= graph
::Neighbors
<'a
, E
, Ix
>;
170 fn neighbors(self, n
: graph
::NodeIndex
<Ix
>) -> graph
::Neighbors
<'a
, E
, Ix
> {
171 Graph
::neighbors(self, n
)
175 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNeighborsDirected
for &'a Graph
<N
, E
, Ty
, Ix
>
180 type NeighborsDirected
= graph
::Neighbors
<'a
, E
, Ix
>;
181 fn neighbors_directed(
183 n
: graph
::NodeIndex
<Ix
>,
185 ) -> graph
::Neighbors
<'a
, E
, Ix
> {
186 Graph
::neighbors_directed(self, n
, d
)
190 #[cfg(feature = "stable_graph")]
191 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNeighborsDirected
for &'a StableGraph
<N
, E
, Ty
, Ix
>
196 type NeighborsDirected
= stable_graph
::Neighbors
<'a
, E
, Ix
>;
197 fn neighbors_directed(self, n
: graph
::NodeIndex
<Ix
>, d
: Direction
) -> Self::NeighborsDirected
{
198 StableGraph
::neighbors_directed(self, n
, d
)
202 #[cfg(feature = "graphmap")]
203 impl<'a
, N
: 'a
, E
, Ty
> IntoNeighborsDirected
for &'a GraphMap
<N
, E
, Ty
>
205 N
: Copy
+ Ord
+ Hash
,
208 type NeighborsDirected
= graphmap
::NeighborsDirected
<'a
, N
, Ty
>;
209 fn neighbors_directed(self, n
: N
, dir
: Direction
) -> Self::NeighborsDirected
{
210 self.neighbors_directed(n
, dir
)
215 /// Access to the edges of each node.
217 /// The edges are, depending on the graph’s edge type:
219 /// - `Directed`: All edges from `a`.
220 /// - `Undirected`: All edges connected to `a`.
222 /// This is an extended version of the trait `IntoNeighbors`; the former
223 /// only iterates over the target node identifiers, while this trait
224 /// yields edge references (trait [`EdgeRef`][er]).
226 /// [er]: trait.EdgeRef.html
227 pub trait IntoEdges
: IntoEdgeReferences
+ IntoNeighbors
{
229 type Edges
: Iterator
<Item
=Self::EdgeRef
>;
231 fn edges(self, a
: Self::NodeId
) -> Self::Edges
;
235 IntoEdges
! {delegate_impl []}
238 /// Access to all edges of each node, in the specified direction.
240 /// The edges are, depending on the direction and the graph’s edge type:
243 /// - `Directed`, `Outgoing`: All edges from `a`.
244 /// - `Directed`, `Incoming`: All edges to `a`.
245 /// - `Undirected`, `Outgoing`: All edges connected to `a`, with `a` being the source of each edge.
246 /// - `Undirected`, `Incoming`: All edges connected to `a`, with `a` being the target of each edge.
248 /// This is an extended version of the trait `IntoNeighborsDirected`; the former
249 /// only iterates over the target node identifiers, while this trait
250 /// yields edge references (trait [`EdgeRef`][er]).
252 /// [er]: trait.EdgeRef.html
253 pub trait IntoEdgesDirected
: IntoEdges
+ IntoNeighborsDirected
{
255 type EdgesDirected
: Iterator
<Item
=Self::EdgeRef
>;
257 fn edges_directed(self, a
: Self::NodeId
, dir
: Direction
) -> Self::EdgesDirected
;
261 IntoEdgesDirected
! {delegate_impl []}
264 /// Access to the sequence of the graph’s `NodeId`s.
265 pub trait IntoNodeIdentifiers
: GraphRef
{
267 type NodeIdentifiers
: Iterator
<Item
=Self::NodeId
>;
269 fn node_identifiers(self) -> Self::NodeIdentifiers
;
273 IntoNodeIdentifiers
! {delegate_impl []}
275 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNodeIdentifiers
for &'a Graph
<N
, E
, Ty
, Ix
>
280 type NodeIdentifiers
= graph
::NodeIndices
<Ix
>;
281 fn node_identifiers(self) -> graph
::NodeIndices
<Ix
> {
282 Graph
::node_indices(self)
286 impl<N
, E
, Ty
, Ix
> NodeCount
for Graph
<N
, E
, Ty
, Ix
>
291 fn node_count(&self) -> usize {
296 #[cfg(feature = "stable_graph")]
297 impl<'a
, N
, E
: 'a
, Ty
, Ix
> IntoNodeIdentifiers
for &'a StableGraph
<N
, E
, Ty
, Ix
>
302 type NodeIdentifiers
= stable_graph
::NodeIndices
<'a
, N
, Ix
>;
303 fn node_identifiers(self) -> Self::NodeIdentifiers
{
304 StableGraph
::node_indices(self)
308 #[cfg(feature = "stable_graph")]
309 impl<N
, E
, Ty
, Ix
> NodeCount
for StableGraph
<N
, E
, Ty
, Ix
>
314 fn node_count(&self) -> usize {
319 IntoNeighborsDirected
! {delegate_impl []}
322 /// Define associated data for nodes and edges
323 pub trait Data
: GraphBase
{
330 Data
! {delegate_impl []}
331 Data
! {delegate_impl [['a, G], G, &'a mut G, deref]}
333 /// An edge reference.
335 /// Edge references are used by traits `IntoEdges` and `IntoEdgeReferences`.
336 pub trait EdgeRef
: Copy
{
340 /// The source node of the edge.
341 fn source(&self) -> Self::NodeId
;
342 /// The target node of the edge.
343 fn target(&self) -> Self::NodeId
;
344 /// A reference to the weight of the edge.
345 fn weight(&self) -> &Self::Weight
;
346 /// The edge’s identifier.
347 fn id(&self) -> Self::EdgeId
;
350 impl<'a
, N
, E
> EdgeRef
for (N
, N
, &'a E
)
355 type EdgeId
= (N
, N
);
358 fn source(&self) -> N
{
361 fn target(&self) -> N
{
364 fn weight(&self) -> &E
{
367 fn id(&self) -> (N
, N
) {
372 /// A node reference.
373 pub trait NodeRef
: Copy
{
376 fn id(&self) -> Self::NodeId
;
377 fn weight(&self) -> &Self::Weight
;
381 /// Access to the sequence of the graph’s nodes
382 pub trait IntoNodeReferences
: Data
+ IntoNodeIdentifiers
{
384 type NodeRef
: NodeRef
<NodeId
=Self::NodeId
, Weight
=Self::NodeWeight
>;
385 type NodeReferences
: Iterator
<Item
=Self::NodeRef
>;
387 fn node_references(self) -> Self::NodeReferences
;
391 IntoNodeReferences
! {delegate_impl []}
393 impl<Id
> NodeRef
for (Id
, ())
399 fn id(&self) -> Self::NodeId
{
402 fn weight(&self) -> &Self::Weight
{
403 static DUMMY
: () = ();
408 impl<'a
, Id
, W
> NodeRef
for (Id
, &'a W
)
414 fn id(&self) -> Self::NodeId
{
417 fn weight(&self) -> &Self::Weight
{
423 /// Access to the sequence of the graph’s edges
424 pub trait IntoEdgeReferences
: Data
+ GraphRef
{
426 type EdgeRef
: EdgeRef
<NodeId
=Self::NodeId
, EdgeId
=Self::EdgeId
,
427 Weight
=Self::EdgeWeight
>;
428 type EdgeReferences
: Iterator
<Item
=Self::EdgeRef
>;
430 fn edge_references(self) -> Self::EdgeReferences
;
434 IntoEdgeReferences
! {delegate_impl [] }
436 #[cfg(feature = "graphmap")]
437 impl<N
, E
, Ty
> Data
for GraphMap
<N
, E
, Ty
>
447 /// Edge kind property (directed or undirected edges)
448 pub trait GraphProp
: GraphBase
{
450 /// The kind edges in the graph.
451 type EdgeType
: EdgeType
;
454 fn is_directed(&self) -> bool
{
455 <Self::EdgeType
>::is_directed()
460 GraphProp
! {delegate_impl []}
462 impl<N
, E
, Ty
, Ix
> GraphProp
for Graph
<N
, E
, Ty
, Ix
>
470 #[cfg(feature = "stable_graph")]
471 impl<N
, E
, Ty
, Ix
> GraphProp
for StableGraph
<N
, E
, Ty
, Ix
>
479 #[cfg(feature = "graphmap")]
480 impl<N
, E
, Ty
> GraphProp
for GraphMap
<N
, E
, Ty
>
488 impl<'a
, N
: 'a
, E
: 'a
, Ty
, Ix
> IntoEdgeReferences
for &'a Graph
<N
, E
, Ty
, Ix
>
493 type EdgeRef
= graph
::EdgeReference
<'a
, E
, Ix
>;
494 type EdgeReferences
= graph
::EdgeReferences
<'a
, E
, Ix
>;
495 fn edge_references(self) -> Self::EdgeReferences
{
496 (*self).edge_references()
501 /// The graph’s `NodeId`s map to indices
502 pub trait NodeIndexable
: GraphBase
{
504 /// Return an upper bound of the node indices in the graph
505 /// (suitable for the size of a bitmap).
506 fn node_bound(self: &Self) -> usize;
507 /// Convert `a` to an integer index.
508 fn to_index(self: &Self, a
: Self::NodeId
) -> usize;
509 /// Convert `i` to a node index
510 fn from_index(self: &Self, i
: usize) -> Self::NodeId
;
514 NodeIndexable
! {delegate_impl []}
517 /// A graph with a known node count.
518 pub trait NodeCount
: GraphBase
{
520 fn node_count(self: &Self) -> usize;
524 NodeCount
! {delegate_impl []}
527 /// The graph’s `NodeId`s map to indices, in a range without holes.
529 /// The graph's node identifiers correspond to exactly the indices
530 /// `0..self.node_bound()`.
531 pub trait NodeCompactIndexable
: NodeIndexable
+ NodeCount { }
534 NodeCompactIndexable
! {delegate_impl []}
536 impl<N
, E
, Ty
, Ix
> NodeIndexable
for Graph
<N
, E
, Ty
, Ix
>
541 fn node_bound(&self) -> usize {
544 fn to_index(&self, ix
: NodeIndex
<Ix
>) -> usize {
547 fn from_index(&self, ix
: usize) -> Self::NodeId
{
552 impl<N
, E
, Ty
, Ix
> NodeCompactIndexable
for Graph
<N
, E
, Ty
, Ix
>
559 /// A mapping for storing the visited status for NodeId `N`.
560 pub trait VisitMap
<N
> {
561 /// Mark `a` as visited.
563 /// Return **true** if this is the first visit, false otherwise.
564 fn visit(&mut self, a
: N
) -> bool
;
566 /// Return whether `a` has been visited before.
567 fn is_visited(&self, a
: &N
) -> bool
;
570 impl<Ix
> VisitMap
<graph
::NodeIndex
<Ix
>> for FixedBitSet
574 fn visit(&mut self, x
: graph
::NodeIndex
<Ix
>) -> bool
{
577 fn is_visited(&self, x
: &graph
::NodeIndex
<Ix
>) -> bool
{
578 self.contains(x
.index())
582 impl<Ix
> VisitMap
<graph
::EdgeIndex
<Ix
>> for FixedBitSet
586 fn visit(&mut self, x
: graph
::EdgeIndex
<Ix
>) -> bool
{
589 fn is_visited(&self, x
: &graph
::EdgeIndex
<Ix
>) -> bool
{
590 self.contains(x
.index())
594 impl<Ix
> VisitMap
<Ix
> for FixedBitSet
598 fn visit(&mut self, x
: Ix
) -> bool
{
601 fn is_visited(&self, x
: &Ix
) -> bool
{
602 self.contains(x
.index())
606 impl<N
, S
> VisitMap
<N
> for HashSet
<N
, S
>
611 fn visit(&mut self, x
: N
) -> bool
{
614 fn is_visited(&self, x
: &N
) -> bool
{
620 /// A graph that can create a map that tracks the visited status of its nodes.
621 pub trait Visitable
: GraphBase
{
623 /// The associated map type
624 type Map
: VisitMap
<Self::NodeId
>;
626 /// Create a new visitor map
627 fn visit_map(self: &Self) -> Self::Map
;
628 /// Reset the visitor map (and resize to new size of graph if needed)
629 fn reset_map(self: &Self, map
: &mut Self::Map
);
632 Visitable
! {delegate_impl []}
634 impl<N
, E
, Ty
, Ix
> GraphBase
for Graph
<N
, E
, Ty
, Ix
>
638 type NodeId
= graph
::NodeIndex
<Ix
>;
639 type EdgeId
= graph
::EdgeIndex
<Ix
>;
642 impl<N
, E
, Ty
, Ix
> Visitable
for Graph
<N
, E
, Ty
, Ix
>
647 type Map
= FixedBitSet
;
648 fn visit_map(&self) -> FixedBitSet
{
649 FixedBitSet
::with_capacity(self.node_count())
652 fn reset_map(&self, map
: &mut Self::Map
) {
654 map
.grow(self.node_count());
658 #[cfg(feature = "stable_graph")]
659 impl<N
, E
, Ty
, Ix
> GraphBase
for StableGraph
<N
, E
, Ty
, Ix
>
663 type NodeId
= graph
::NodeIndex
<Ix
>;
664 type EdgeId
= graph
::EdgeIndex
<Ix
>;
667 #[cfg(feature = "stable_graph")]
668 impl<N
, E
, Ty
, Ix
> Visitable
for StableGraph
<N
, E
, Ty
, Ix
>
673 type Map
= FixedBitSet
;
674 fn visit_map(&self) -> FixedBitSet
{
675 FixedBitSet
::with_capacity(self.node_bound())
677 fn reset_map(&self, map
: &mut Self::Map
) {
679 map
.grow(self.node_bound());
683 #[cfg(feature = "stable_graph")]
684 impl<N
, E
, Ty
, Ix
> Data
for StableGraph
<N
, E
, Ty
, Ix
>
693 #[cfg(feature = "graphmap")]
694 impl<N
, E
, Ty
> GraphBase
for GraphMap
<N
, E
, Ty
>
699 type EdgeId
= (N
, N
);
702 #[cfg(feature = "graphmap")]
703 impl<N
, E
, Ty
> Visitable
for GraphMap
<N
, E
, Ty
>
705 N
: Copy
+ Ord
+ Hash
,
708 type Map
= HashSet
<N
>;
709 fn visit_map(&self) -> HashSet
<N
> {
710 HashSet
::with_capacity(self.node_count())
712 fn reset_map(&self, map
: &mut Self::Map
) {
718 /// Create or access the adjacency matrix of a graph.
720 /// The implementor can either create an adjacency matrix, or it can return
721 /// a placeholder if it has the needed representation internally.
722 pub trait GetAdjacencyMatrix
: GraphBase
{
724 /// The associated adjacency matrix type
727 /// Create the adjacency matrix
728 fn adjacency_matrix(self: &Self) -> Self::AdjMatrix
;
729 /// Return true if there is an edge from `a` to `b`, false otherwise.
731 /// Computes in O(1) time.
732 fn is_adjacent(self: &Self, matrix
: &Self::AdjMatrix
, a
: Self::NodeId
, b
: Self::NodeId
) -> bool
;
736 GetAdjacencyMatrix
! {delegate_impl []}
738 #[cfg(feature = "graphmap")]
739 /// The `GraphMap` keeps an adjacency matrix internally.
740 impl<N
, E
, Ty
> GetAdjacencyMatrix
for GraphMap
<N
, E
, Ty
>
742 N
: Copy
+ Ord
+ Hash
,
747 fn adjacency_matrix(&self) {}
749 fn is_adjacent(&self, _
: &(), a
: N
, b
: N
) -> bool
{
750 self.contains_edge(a
, b
)