petgraph/
adj.rs

1//! Simple adjacency list.
2use fixedbitset::FixedBitSet;
3use crate::iter_format::NoPretty;
4use core::fmt;
5use core::ops::Range;
6use crate::visit::{self, EdgeRef, IntoEdgeReferences, IntoNeighbors, NodeCount};
7use crate::data::{Build, DataMap, DataMapMut};
8use alloc::{vec::Vec, boxed::Box};
9
10#[doc(no_inline)]
11pub use crate::graph::{DefaultIx, IndexType};
12
13/// Adjacency list node index type, a plain integer.
14pub type NodeIndex<Ix = DefaultIx> = Ix;
15
16/// Adjacency list edge index type, a pair of integers.
17#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
18pub struct EdgeIndex<Ix = DefaultIx>
19where
20    Ix: IndexType,
21{
22    /// Source of the edge.
23    from: NodeIndex<Ix>,
24    /// Index of the sucessor in the successor list.
25    successor_index: usize,
26}
27
28iterator_wrap! {
29impl (Iterator) for
30/// An Iterator over the indices of the outgoing edges from a node.
31///
32/// It does not borrow the graph during iteration.
33struct OutgoingEdgeIndices <Ix> where { Ix: IndexType }
34item: EdgeIndex<Ix>,
35iter: core::iter::Map<core::iter::Zip<Range<usize>, core::iter::Repeat<NodeIndex<Ix>>>, fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix>>,
36}
37
38/// Weighted sucessor
39#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
40struct WSuc<E, Ix: IndexType> {
41    /// Index of the sucessor.
42    suc: Ix,
43    /// Weight of the edge to `suc`.
44    weight: E,
45}
46
47/// One row of the adjacency list.
48type Row<E, Ix> = Vec<WSuc<E, Ix>>;
49type RowIter<'a, E, Ix> = core::slice::Iter<'a, WSuc<E, Ix>>;
50
51iterator_wrap! {
52impl (Iterator DoubleEndedIterator ExactSizeIterator) for
53/// An iterator over the indices of the neighbors of a node.
54struct Neighbors<'a, E, Ix> where { Ix: IndexType }
55item: NodeIndex<Ix>,
56iter: core::iter::Map<RowIter<'a, E, Ix>, fn(&WSuc<E, Ix>) -> NodeIndex<Ix>>,
57}
58
59/// A reference to an edge of the graph.
60#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
61pub struct EdgeReference<'a, E, Ix: IndexType> {
62    /// index of the edge
63    id: EdgeIndex<Ix>,
64    /// a reference to the corresponding item in the adjacency list
65    edge: &'a WSuc<E, Ix>,
66}
67
68impl<'a, E, Ix: IndexType> Copy for EdgeReference<'a, E, Ix> {}
69impl<'a, E, Ix: IndexType> Clone for EdgeReference<'a, E, Ix> {
70    fn clone(&self) -> Self {
71        EdgeReference {
72            id: self.id,
73            edge: self.edge,
74        }
75    }
76}
77
78impl<'a, E, Ix: IndexType> visit::EdgeRef for EdgeReference<'a, E, Ix> {
79    type NodeId = NodeIndex<Ix>;
80    type EdgeId = EdgeIndex<Ix>;
81    type Weight = E;
82    fn source(&self) -> Self::NodeId {
83        self.id.from
84    }
85    fn target(&self) -> Self::NodeId {
86        self.edge.suc
87    }
88    fn id(&self) -> Self::EdgeId {
89        self.id
90    }
91    fn weight(&self) -> &Self::Weight {
92        &self.edge.weight
93    }
94}
95
96pub struct EdgeIndices<'a, E, Ix: IndexType> {
97    rows: core::iter::Enumerate<core::slice::Iter<'a, Row<E, Ix>>>,
98    row_index: usize,
99    row_len: usize,
100    cur: usize,
101}
102
103impl<'a, E, Ix: IndexType> Iterator for EdgeIndices<'a, E, Ix> {
104    type Item = EdgeIndex<Ix>;
105    fn next(&mut self) -> Option<EdgeIndex<Ix>> {
106        loop {
107            if self.cur < self.row_len {
108                let res = self.cur;
109                self.cur += 1;
110                return Some(EdgeIndex {
111                    from: Ix::new(self.row_index),
112                    successor_index: res,
113                });
114            } else {
115                match self.rows.next() {
116                    Some((index, row)) => {
117                        self.row_index = index;
118                        self.cur = 0;
119                        self.row_len = row.len();
120                    }
121                    None => return None,
122                }
123            }
124        }
125    }
126}
127
128iterator_wrap! {
129    impl (Iterator DoubleEndedIterator ExactSizeIterator) for
130    /// An iterator over all node indices in the graph.
131    struct NodeIndices <Ix> where {}
132    item: Ix,
133    iter: core::iter::Map<Range<usize>, fn(usize) -> Ix>,
134}
135
136/// An adjacency list with labeled edges.
137///
138/// Can be interpreted as a directed graph
139/// with unweighted nodes.
140///
141/// This is the most simple adjacency list you can imagine. `Graph`, in contrast,
142/// maintains both the list of successors and predecessors for each node,
143/// which is a different trade-off.
144///
145/// Allows parallel edges and self-loops.
146///
147/// This data structure is append-only (except for [`clear`]), so indices
148/// returned at some point for a given graph will stay valid with this same
149/// graph until it is dropped or [`clear`] is called.
150///
151/// Space consumption: **O(|E|)**.
152#[derive(Clone, Default)]
153pub struct List<E, Ix = DefaultIx>
154where
155    Ix: IndexType,
156{
157    suc: Vec<Row<E, Ix>>,
158}
159
160impl<E, Ix: IndexType> List<E, Ix> {
161    /// Creates a new, empty adjacency list.
162    pub fn new() -> List<E, Ix> {
163        List { suc: Vec::new() }
164    }
165
166    /// Creates a new, empty adjacency list tailored for `nodes` nodes.
167    pub fn with_capacity(nodes: usize) -> List<E, Ix> {
168        List {
169            suc: Vec::with_capacity(nodes),
170        }
171    }
172
173    /// Removes all nodes and edges from the list.
174    pub fn clear(&mut self) {
175        self.suc.clear()
176    }
177
178    /// Returns the number of edges in the list
179    ///
180    /// Computes in **O(|V|)** time.
181    pub fn edge_count(&self) -> usize {
182        self.suc.iter().map(|x| x.len()).sum()
183    }
184
185    /// Adds a new node to the list. This allocates a new `Vec` and then should
186    /// run in amortized **O(1)** time.
187    pub fn add_node(&mut self) -> NodeIndex<Ix> {
188        let i = self.suc.len();
189        self.suc.push(Vec::new());
190        Ix::new(i)
191    }
192
193    /// Adds a new node to the list. This allocates a new `Vec` and then should
194    /// run in amortized **O(1)** time.
195    pub fn add_node_with_capacity(&mut self, successors: usize) -> NodeIndex<Ix> {
196        let i = self.suc.len();
197        self.suc.push(Vec::with_capacity(successors));
198        Ix::new(i)
199    }
200
201    /// Adds a new node to the list by giving its list of successors and the corresponding
202    /// weigths.
203    pub fn add_node_from_edges<I: Iterator<Item = (NodeIndex<Ix>, E)>>(
204        &mut self,
205        edges: I,
206    ) -> NodeIndex<Ix> {
207        let i = self.suc.len();
208        self.suc
209            .push(edges.map(|(suc, weight)| WSuc { suc, weight }).collect());
210        Ix::new(i)
211    }
212
213    /// Add an edge from `a` to `b` to the graph, with its associated
214    /// data `weight`.
215    ///
216    /// Return the index of the new edge.
217    ///
218    /// Computes in **O(1)** time.
219    ///
220    /// **Panics** if the source node does not exist.<br>
221    ///
222    /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
223    /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
224    pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
225        if b.index() >= self.suc.len() {
226            panic!("{} is not a valid node index for a {} nodes adjacency list", b.index(), self.suc.len());
227        }
228        let row = &mut self.suc[a.index()];
229        let rank = row.len();
230        row.push(WSuc { suc: b, weight });
231        EdgeIndex {
232            from: a,
233            successor_index: rank,
234        }
235    }
236
237    fn get_edge(&self, e: EdgeIndex<Ix>) -> Option<&WSuc<E, Ix>> {
238        self.suc
239            .get(e.from.index())
240            .and_then(|row| row.get(e.successor_index))
241    }
242
243    fn get_edge_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut WSuc<E, Ix>> {
244        self.suc
245            .get_mut(e.from.index())
246            .and_then(|row| row.get_mut(e.successor_index))
247    }
248
249    /// Accesses the source and target of edge `e`
250    ///
251    /// Computes in **O(1)**
252    pub fn edge_endpoints(&self, e: EdgeIndex<Ix>) -> Option<(NodeIndex<Ix>, NodeIndex<Ix>)> {
253        self.get_edge(e).map(|x| (e.from, x.suc))
254    }
255
256    pub fn edge_indices_from(&self, a: NodeIndex<Ix>) -> OutgoingEdgeIndices<Ix> {
257        let proj: fn((usize, NodeIndex<Ix>)) -> EdgeIndex<Ix> =
258            |(successor_index, from)| EdgeIndex {
259                from,
260                successor_index,
261            };
262        let iter = (0..(self.suc[a.index()].len()))
263            .zip(core::iter::repeat(a))
264            .map(proj);
265        OutgoingEdgeIndices { iter }
266    }
267
268    /// Lookups whether there is an edge from `a` to `b`.
269    ///
270    /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
271    pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
272        match self.suc.get(a.index()) {
273            None => false,
274            Some(row) => row.iter().any(|x| x.suc == b),
275        }
276    }
277
278    /// Lookups whether there is an edge from `a` to `b`.
279    ///
280    /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
281    pub fn find_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Option<EdgeIndex<Ix>> {
282        self.suc.get(a.index()).and_then(|row| {
283            row.iter()
284                .enumerate()
285                .find(|(_, x)| x.suc == b)
286                .map(|(i, _)| EdgeIndex {
287                    from: a,
288                    successor_index: i,
289                })
290        })
291    }
292
293    /// Returns an iterator over all node indices of the graph.
294    ///
295    /// Consuming the whole iterator take **O(|V|)**.
296    pub fn node_indices(&self) -> NodeIndices<Ix> {
297        NodeIndices {
298            iter: (0..self.suc.len()).map(Ix::new),
299        }
300    }
301
302    /// Returns an iterator over all edge indices of the graph.
303    ///
304    /// Consuming the whole iterator take **O(|V| + |E|)**.
305    pub fn edge_indices(&self) -> EdgeIndices<E, Ix> {
306        EdgeIndices {
307            rows: self.suc.iter().enumerate(),
308            row_index: 0,
309            row_len: 0,
310            cur: 0,
311        }
312    }
313}
314
315
316/// A very simple adjacency list with no node or label weights.
317pub type UnweightedList<Ix> = List<(), Ix>;
318
319
320impl<E, Ix: IndexType> Build for List<E, Ix> {
321    /// Adds a new node to the list. This allocates a new `Vec` and then should
322    /// run in amortized **O(1)** time.
323    fn add_node(&mut self, _weight: ()) -> NodeIndex<Ix> {
324        self.add_node()
325    }
326
327    /// Add an edge from `a` to `b` to the graph, with its associated
328    /// data `weight`.
329    ///
330    /// Return the index of the new edge.
331    ///
332    /// Computes in **O(1)** time.
333    ///
334    /// **Panics** if the source node does not exist.<br>
335    ///
336    /// **Note:** `List` allows adding parallel (“duplicate”) edges. If you want
337    /// to avoid this, use [`.update_edge(a, b, weight)`](#method.update_edge) instead.
338    fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> Option<EdgeIndex<Ix>> {
339        Some(self.add_edge(a, b, weight))
340    }
341
342    /// Updates or adds an edge from `a` to `b` to the graph, with its associated
343    /// data `weight`.
344    ///
345    /// Return the index of the new edge.
346    ///
347    /// Computes in **O(e')** time, where **e'** is the number of successors of `a`.
348    ///
349    /// **Panics** if the source node does not exist.<br>
350    fn update_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> EdgeIndex<Ix> {
351        let row = &mut self.suc[a.index()];
352        for (i, info) in row.iter_mut().enumerate() {
353            if info.suc == b {
354                info.weight = weight;
355                return EdgeIndex {
356                    from: a,
357                    successor_index: i,
358                };
359            }
360        }
361        let rank = row.len();
362        row.push(WSuc { suc: b, weight });
363        EdgeIndex {
364            from: a,
365            successor_index: rank,
366        }
367    }
368}
369
370
371
372impl<'a, E, Ix> fmt::Debug for EdgeReferences<'a, E, Ix>
373where
374    E: fmt::Debug,
375    Ix: IndexType,
376{
377    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378        let mut edge_list = f.debug_list();
379        let iter: Self = self.clone();
380        for e in iter {
381            if core::mem::size_of::<E>() != 0 {
382                edge_list.entry(&(
383                    NoPretty((e.source().index(), e.target().index())),
384                    e.weight(),
385                ));
386            } else {
387                edge_list.entry(&NoPretty((e.source().index(), e.target().index())));
388            }
389        }
390        edge_list.finish()
391    }
392}
393
394impl<E, Ix> fmt::Debug for List<E, Ix>
395where
396    E: fmt::Debug,
397    Ix: IndexType,
398{
399    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
400        let mut fmt_struct = f.debug_struct("adj::List");
401        fmt_struct.field("node_count", &self.node_count());
402        fmt_struct.field("edge_count", &self.edge_count());
403        if self.edge_count() > 0 {
404            fmt_struct.field("edges", &self.edge_references());
405        }
406        fmt_struct.finish()
407    }
408}
409
410impl<E, Ix> visit::GraphBase for List<E, Ix>
411where
412    Ix: IndexType,
413{
414    type NodeId = NodeIndex<Ix>;
415    type EdgeId = EdgeIndex<Ix>;
416}
417
418impl<E, Ix> visit::Visitable for List<E, Ix>
419where
420    Ix: IndexType,
421{
422    type Map = FixedBitSet;
423    fn visit_map(&self) -> FixedBitSet {
424        FixedBitSet::with_capacity(self.node_count())
425    }
426    fn reset_map(&self, map: &mut Self::Map) {
427        map.clear();
428        map.grow(self.node_count());
429    }
430}
431
432impl<'a, E, Ix: IndexType> visit::IntoNodeIdentifiers for &'a List<E, Ix> {
433    type NodeIdentifiers = NodeIndices<Ix>;
434    fn node_identifiers(self) -> NodeIndices<Ix> {
435        self.node_indices()
436    }
437}
438
439impl<Ix: IndexType> visit::NodeRef for NodeIndex<Ix> {
440    type NodeId = NodeIndex<Ix>;
441    type Weight = ();
442    fn id(&self) -> Self::NodeId {
443        *self
444    }
445    fn weight(&self) -> &Self::Weight {
446        &()
447    }
448}
449
450impl<'a, Ix: IndexType, E> visit::IntoNodeReferences for &'a List<E, Ix> {
451    type NodeRef = NodeIndex<Ix>;
452    type NodeReferences = NodeIndices<Ix>;
453    fn node_references(self) -> Self::NodeReferences {
454        self.node_indices()
455    }
456}
457
458impl<E, Ix: IndexType> visit::Data for List<E, Ix> {
459    type NodeWeight = ();
460    type EdgeWeight = E;
461}
462
463impl<'a, E, Ix: IndexType> IntoNeighbors for &'a List<E, Ix> {
464    type Neighbors = Neighbors<'a, E, Ix>;
465    /// Returns an iterator of all nodes with an edge starting from `a`.
466    /// Panics if `a` is out of bounds.
467    /// Use [`List::edge_indices_from`] instead if you do not want to borrow the adjacency list while
468    /// iterating.
469    fn neighbors(self, a: NodeIndex<Ix>) -> Self::Neighbors {
470        let proj: fn(&WSuc<E, Ix>) -> NodeIndex<Ix> = |x| x.suc;
471        let iter = self.suc[a.index()].iter().map(proj);
472        Neighbors { iter }
473    }
474}
475
476type SomeIter<'a, E, Ix> = core::iter::Map<
477    core::iter::Zip<core::iter::Enumerate<RowIter<'a, E, Ix>>, core::iter::Repeat<Ix>>,
478    fn(((usize, &'a WSuc<E, Ix>), Ix)) -> EdgeReference<'a, E, Ix>,
479>;
480
481iterator_wrap! {
482impl (Iterator) for
483/// An iterator over the [`EdgeReference`] of all the edges of the graph.
484struct EdgeReferences<'a, E, Ix> where { Ix: IndexType }
485item: EdgeReference<'a, E, Ix>,
486iter: core::iter::FlatMap<
487    core::iter::Enumerate<
488        core::slice::Iter<'a, Row<E, Ix>>
489    >,
490    SomeIter<'a, E, Ix>,
491    fn(
492        (usize, &'a Vec<WSuc<E, Ix>>)
493    ) -> SomeIter<'a, E, Ix>,
494>,
495}
496
497impl<'a, E, Ix: IndexType> Clone for EdgeReferences<'a, E, Ix> {
498    fn clone(&self) -> Self {
499        EdgeReferences {
500            iter: self.iter.clone(),
501        }
502    }
503}
504
505fn proj1<'a, E, Ix: IndexType>(
506    ((successor_index, edge), from): ((usize, &'a WSuc<E, Ix>), Ix),
507) -> EdgeReference<'a, E, Ix> {
508    let id = EdgeIndex {
509        from,
510        successor_index,
511    };
512    EdgeReference { id, edge }
513}
514fn proj2<'a, E, Ix: IndexType>(
515    (row_index, row): (usize, &'a Vec<WSuc<E, Ix>>),
516) -> SomeIter<'a, E, Ix> {
517    row.iter()
518        .enumerate()
519        .zip(core::iter::repeat(Ix::new(row_index)))
520        .map(proj1 as _)
521}
522
523impl<'a, Ix: IndexType, E> visit::IntoEdgeReferences for &'a List<E, Ix> {
524    type EdgeRef = EdgeReference<'a, E, Ix>;
525    type EdgeReferences = EdgeReferences<'a, E, Ix>;
526    fn edge_references(self) -> Self::EdgeReferences {
527        let iter = self.suc.iter().enumerate().flat_map(proj2 as _);
528        EdgeReferences { iter }
529    }
530}
531
532iterator_wrap! {
533impl (Iterator) for
534/// Iterator over the [`EdgeReference`] of the outgoing edges from a node.
535struct OutgoingEdgeReferences<'a, E, Ix> where { Ix: IndexType }
536item: EdgeReference<'a, E, Ix>,
537iter: SomeIter<'a, E, Ix>,
538}
539
540impl<'a, Ix: IndexType, E> visit::IntoEdges for &'a List<E, Ix> {
541    type Edges = OutgoingEdgeReferences<'a, E, Ix>;
542    fn edges(self, a: Self::NodeId) -> Self::Edges {
543        let iter = self.suc[a.index()]
544            .iter()
545            .enumerate()
546            .zip(core::iter::repeat(a))
547            .map(proj1 as _);
548        OutgoingEdgeReferences { iter }
549    }
550}
551
552impl<E, Ix: IndexType> visit::GraphProp for List<E, Ix> {
553    type EdgeType = crate::Directed;
554    fn is_directed(&self) -> bool { true }
555}
556
557impl <E, Ix: IndexType> NodeCount for List<E, Ix> {
558    /// Returns the number of nodes in the list
559    ///
560    /// Computes in **O(1)** time.
561    fn node_count(&self) -> usize {
562        self.suc.len()
563    }
564}
565
566impl<E, Ix: IndexType> visit::NodeIndexable for List<E, Ix> {
567    fn node_bound(&self) -> usize {
568        self.node_count()
569    }
570    #[inline]
571    fn to_index(&self, a: Self::NodeId) -> usize {
572        a.index()
573    }
574    #[inline]
575    fn from_index(&self, i: usize) -> Self::NodeId {
576        Ix::new(i)
577    }
578}
579
580impl<E, Ix: IndexType> visit::NodeCompactIndexable for List<E, Ix> {}
581
582impl<E, Ix: IndexType> DataMap for List<E, Ix> {
583    fn node_weight(&self, n: Self::NodeId) -> Option<&()> {
584        if n.index() < self.suc.len() {
585            Some(&())
586        } else {
587            None
588        }
589    }
590
591    /// Accesses the weight of edge `e`
592    ///
593    /// Computes in **O(1)**
594    fn edge_weight(&self, e: EdgeIndex<Ix>) -> Option<&E> {
595        self.get_edge(e).map(|x| &x.weight)
596    }
597}
598
599impl<E, Ix: IndexType> DataMapMut for List<E, Ix> {
600    fn node_weight_mut(&mut self, n: Self::NodeId) -> Option<&mut ()> {
601        if n.index() < self.suc.len() {
602            // A hack to produce a &'static mut ()
603            // It does not actually allocate according to godbolt
604            let b = Box::new(());
605            Some(Box::leak(b))
606        } else {
607            None
608        }
609    }
610    /// Accesses the weight of edge `e`
611    ///
612    /// Computes in **O(1)**
613    fn edge_weight_mut(&mut self, e: EdgeIndex<Ix>) -> Option<&mut E> {
614        self.get_edge_mut(e).map(|x| &mut x.weight)
615    }
616}
617