Skip to main content

petgraph/
adj.rs

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