1 //! Compressed Sparse Row (CSR) is a sparse adjacency matrix graph.
2 
3 use std::cmp::{max, Ordering};
4 use std::iter::{Enumerate, Zip};
5 use std::marker::PhantomData;
6 use std::ops::{Index, IndexMut, Range};
7 use std::slice::Windows;
8 
9 use crate::visit::{
10     Data, EdgeCount, EdgeRef, GetAdjacencyMatrix, GraphBase, GraphProp, IntoEdgeReferences,
11     IntoEdges, IntoNeighbors, IntoNodeIdentifiers, IntoNodeReferences, NodeCompactIndexable,
12     NodeCount, NodeIndexable, Visitable,
13 };
14 
15 use crate::util::zip;
16 
17 #[doc(no_inline)]
18 pub use crate::graph::{DefaultIx, IndexType};
19 
20 use crate::{Directed, EdgeType, IntoWeightedEdge};
21 
22 /// Csr node index type, a plain integer.
23 pub type NodeIndex<Ix = DefaultIx> = Ix;
24 /// Csr edge index type, a plain integer.
25 pub type EdgeIndex = usize;
26 
27 const BINARY_SEARCH_CUTOFF: usize = 32;
28 
29 /// Compressed Sparse Row ([`CSR`]) is a sparse adjacency matrix graph.
30 ///
31 /// `CSR` is parameterized over:
32 ///
33 /// - Associated data `N` for nodes and `E` for edges, called *weights*.
34 ///   The associated data can be of arbitrary type.
35 /// - Edge type `Ty` that determines whether the graph edges are directed or undirected.
36 /// - Index type `Ix`, which determines the maximum size of the graph.
37 ///
38 ///
39 /// Using **O(|E| + |V|)** space.
40 ///
41 /// Self loops are allowed, no parallel edges.
42 ///
43 /// Fast iteration of the outgoing edges of a vertex.
44 ///
45 /// [`CSR`]: https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format)
46 #[derive(Debug)]
47 pub struct Csr<N = (), E = (), Ty = Directed, Ix = DefaultIx> {
48     /// Column of next edge
49     column: Vec<NodeIndex<Ix>>,
50     /// weight of each edge; lock step with column
51     edges: Vec<E>,
52     /// Index of start of row Always node_count + 1 long.
53     /// Last element is always equal to column.len()
54     row: Vec<usize>,
55     node_weights: Vec<N>,
56     edge_count: usize,
57     ty: PhantomData<Ty>,
58 }
59 
60 impl<N, E, Ty, Ix> Default for Csr<N, E, Ty, Ix>
61 where
62     Ty: EdgeType,
63     Ix: IndexType,
64 {
default() -> Self65     fn default() -> Self {
66         Self::new()
67     }
68 }
69 
70 impl<N: Clone, E: Clone, Ty, Ix: Clone> Clone for Csr<N, E, Ty, Ix> {
clone(&self) -> Self71     fn clone(&self) -> Self {
72         Csr {
73             column: self.column.clone(),
74             edges: self.edges.clone(),
75             row: self.row.clone(),
76             node_weights: self.node_weights.clone(),
77             edge_count: self.edge_count,
78             ty: self.ty,
79         }
80     }
81 }
82 
83 impl<N, E, Ty, Ix> Csr<N, E, Ty, Ix>
84 where
85     Ty: EdgeType,
86     Ix: IndexType,
87 {
88     /// Create an empty `Csr`.
new() -> Self89     pub fn new() -> Self {
90         Csr {
91             column: vec![],
92             edges: vec![],
93             row: vec![0; 1],
94             node_weights: vec![],
95             edge_count: 0,
96             ty: PhantomData,
97         }
98     }
99 
100     /// Create a new `Csr` with `n` nodes. `N` must implement [`Default`] for the weight of each node.
101     ///
102     /// [`Default`]: https://doc.rust-lang.org/nightly/core/default/trait.Default.html
103     ///
104     /// # Example
105     /// ```rust
106     /// use petgraph::csr::Csr;
107     /// use petgraph::prelude::*;
108     ///
109     /// let graph = Csr::<u8,()>::with_nodes(5);
110     /// assert_eq!(graph.node_count(),5);
111     /// assert_eq!(graph.edge_count(),0);
112     ///
113     /// assert_eq!(graph[0],0);
114     /// assert_eq!(graph[4],0);
115     /// ```
with_nodes(n: usize) -> Self where N: Default,116     pub fn with_nodes(n: usize) -> Self
117     where
118         N: Default,
119     {
120         Csr {
121             column: Vec::new(),
122             edges: Vec::new(),
123             row: vec![0; n + 1],
124             node_weights: (0..n).map(|_| N::default()).collect(),
125             edge_count: 0,
126             ty: PhantomData,
127         }
128     }
129 }
130 
131 /// Csr creation error: edges were not in sorted order.
132 #[derive(Clone, Debug)]
133 pub struct EdgesNotSorted {
134     first_error: (usize, usize),
135 }
136 
137 impl<N, E, Ix> Csr<N, E, Directed, Ix>
138 where
139     Ix: IndexType,
140 {
141     /// Create a new `Csr` from a sorted sequence of edges
142     ///
143     /// Edges **must** be sorted and unique, where the sort order is the default
144     /// order for the pair *(u, v)* in Rust (*u* has priority).
145     ///
146     /// Computes in **O(|E| + |V|)** time.
147     /// # Example
148     /// ```rust
149     /// use petgraph::csr::Csr;
150     /// use petgraph::prelude::*;
151     ///
152     /// let graph = Csr::<(),()>::from_sorted_edges(&[
153     ///                     (0, 1), (0, 2),
154     ///                     (1, 0), (1, 2), (1, 3),
155     ///                     (2, 0),
156     ///                     (3, 1),
157     /// ]);
158     /// ```
from_sorted_edges<Edge>(edges: &[Edge]) -> Result<Self, EdgesNotSorted> where Edge: Clone + IntoWeightedEdge<E, NodeId = NodeIndex<Ix>>, N: Default,159     pub fn from_sorted_edges<Edge>(edges: &[Edge]) -> Result<Self, EdgesNotSorted>
160     where
161         Edge: Clone + IntoWeightedEdge<E, NodeId = NodeIndex<Ix>>,
162         N: Default,
163     {
164         let max_node_id = match edges
165             .iter()
166             .map(|edge| {
167                 let (x, y, _) = edge.clone().into_weighted_edge();
168                 max(x.index(), y.index())
169             })
170             .max()
171         {
172             None => return Ok(Self::with_nodes(0)),
173             Some(x) => x,
174         };
175         let mut self_ = Self::with_nodes(max_node_id + 1);
176         let mut iter = edges.iter().cloned().peekable();
177         {
178             let mut rows = self_.row.iter_mut();
179 
180             let mut rstart = 0;
181             let mut last_target;
182             'outer: for (node, r) in (&mut rows).enumerate() {
183                 *r = rstart;
184                 last_target = None;
185                 'inner: loop {
186                     if let Some(edge) = iter.peek() {
187                         let (n, m, weight) = edge.clone().into_weighted_edge();
188                         // check that the edges are in increasing sequence
189                         if node > n.index() {
190                             return Err(EdgesNotSorted {
191                                 first_error: (n.index(), m.index()),
192                             });
193                         }
194                         /*
195                         debug_assert!(node <= n.index(),
196                                       concat!("edges are not sorted, ",
197                                               "failed assertion source {:?} <= {:?} ",
198                                               "for edge {:?}"),
199                                       node, n, (n, m));
200                                       */
201                         if n.index() != node {
202                             break 'inner;
203                         }
204                         // check that the edges are in increasing sequence
205                         /*
206                         debug_assert!(last_target.map_or(true, |x| m > x),
207                                       "edges are not sorted, failed assertion {:?} < {:?}",
208                                       last_target, m);
209                                       */
210                         if !last_target.map_or(true, |x| m > x) {
211                             return Err(EdgesNotSorted {
212                                 first_error: (n.index(), m.index()),
213                             });
214                         }
215                         last_target = Some(m);
216                         self_.column.push(m);
217                         self_.edges.push(weight);
218                         rstart += 1;
219                     } else {
220                         break 'outer;
221                     }
222                     iter.next();
223                 }
224             }
225             for r in rows {
226                 *r = rstart;
227             }
228         }
229 
230         Ok(self_)
231     }
232 }
233 
234 impl<N, E, Ty, Ix> Csr<N, E, Ty, Ix>
235 where
236     Ty: EdgeType,
237     Ix: IndexType,
238 {
node_count(&self) -> usize239     pub fn node_count(&self) -> usize {
240         self.row.len() - 1
241     }
242 
edge_count(&self) -> usize243     pub fn edge_count(&self) -> usize {
244         if self.is_directed() {
245             self.column.len()
246         } else {
247             self.edge_count
248         }
249     }
250 
is_directed(&self) -> bool251     pub fn is_directed(&self) -> bool {
252         Ty::is_directed()
253     }
254 
255     /// Remove all edges
clear_edges(&mut self)256     pub fn clear_edges(&mut self) {
257         self.column.clear();
258         self.edges.clear();
259         for r in &mut self.row {
260             *r = 0;
261         }
262         if !self.is_directed() {
263             self.edge_count = 0;
264         }
265     }
266 
267     /// Adds a new node with the given weight, returning the corresponding node index.
add_node(&mut self, weight: N) -> NodeIndex<Ix>268     pub fn add_node(&mut self, weight: N) -> NodeIndex<Ix> {
269         let i = self.row.len() - 1;
270         self.row.insert(i, self.column.len());
271         self.node_weights.insert(i, weight);
272         Ix::new(i)
273     }
274 
275     /// Return `true` if the edge was added
276     ///
277     /// If you add all edges in row-major order, the time complexity
278     /// is **O(|V|·|E|)** for the whole operation.
279     ///
280     /// **Panics** if `a` or `b` are out of bounds.
add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool where E: Clone,281     pub fn add_edge(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool
282     where
283         E: Clone,
284     {
285         let ret = self.add_edge_(a, b, weight.clone());
286         if ret && !self.is_directed() {
287             self.edge_count += 1;
288         }
289         if ret && !self.is_directed() && a != b {
290             let _ret2 = self.add_edge_(b, a, weight);
291             debug_assert_eq!(ret, _ret2);
292         }
293         ret
294     }
295 
296     // Return false if the edge already exists
add_edge_(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool297     fn add_edge_(&mut self, a: NodeIndex<Ix>, b: NodeIndex<Ix>, weight: E) -> bool {
298         assert!(a.index() < self.node_count() && b.index() < self.node_count());
299         // a x b is at (a, b) in the matrix
300 
301         // find current range of edges from a
302         let pos = match self.find_edge_pos(a, b) {
303             Ok(_) => return false, /* already exists */
304             Err(i) => i,
305         };
306         self.column.insert(pos, b);
307         self.edges.insert(pos, weight);
308         // update row vector
309         for r in &mut self.row[a.index() + 1..] {
310             *r += 1;
311         }
312         true
313     }
314 
find_edge_pos(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Result<usize, usize>315     fn find_edge_pos(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> Result<usize, usize> {
316         let (index, neighbors) = self.neighbors_of(a);
317         if neighbors.len() < BINARY_SEARCH_CUTOFF {
318             for (i, elt) in neighbors.iter().enumerate() {
319                 match elt.cmp(&b) {
320                     Ordering::Equal => return Ok(i + index),
321                     Ordering::Greater => return Err(i + index),
322                     Ordering::Less => {}
323                 }
324             }
325             Err(neighbors.len() + index)
326         } else {
327             match neighbors.binary_search(&b) {
328                 Ok(i) => Ok(i + index),
329                 Err(i) => Err(i + index),
330             }
331         }
332     }
333 
334     /// Computes in **O(log |V|)** time.
335     ///
336     /// **Panics** if the node `a` does not exist.
contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool337     pub fn contains_edge(&self, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
338         self.find_edge_pos(a, b).is_ok()
339     }
340 
neighbors_range(&self, a: NodeIndex<Ix>) -> Range<usize>341     fn neighbors_range(&self, a: NodeIndex<Ix>) -> Range<usize> {
342         let index = self.row[a.index()];
343         let end = self
344             .row
345             .get(a.index() + 1)
346             .cloned()
347             .unwrap_or(self.column.len());
348         index..end
349     }
350 
neighbors_of(&self, a: NodeIndex<Ix>) -> (usize, &[Ix])351     fn neighbors_of(&self, a: NodeIndex<Ix>) -> (usize, &[Ix]) {
352         let r = self.neighbors_range(a);
353         (r.start, &self.column[r])
354     }
355 
356     /// Computes in **O(1)** time.
357     ///
358     /// **Panics** if the node `a` does not exist.
out_degree(&self, a: NodeIndex<Ix>) -> usize359     pub fn out_degree(&self, a: NodeIndex<Ix>) -> usize {
360         let r = self.neighbors_range(a);
361         r.end - r.start
362     }
363 
364     /// Computes in **O(1)** time.
365     ///
366     /// **Panics** if the node `a` does not exist.
neighbors_slice(&self, a: NodeIndex<Ix>) -> &[NodeIndex<Ix>]367     pub fn neighbors_slice(&self, a: NodeIndex<Ix>) -> &[NodeIndex<Ix>] {
368         self.neighbors_of(a).1
369     }
370 
371     /// Computes in **O(1)** time.
372     ///
373     /// **Panics** if the node `a` does not exist.
edges_slice(&self, a: NodeIndex<Ix>) -> &[E]374     pub fn edges_slice(&self, a: NodeIndex<Ix>) -> &[E] {
375         &self.edges[self.neighbors_range(a)]
376     }
377 
378     /// Return an iterator of all edges of `a`.
379     ///
380     /// - `Directed`: Outgoing edges from `a`.
381     /// - `Undirected`: All edges connected to `a`.
382     ///
383     /// **Panics** if the node `a` does not exist.<br>
384     /// Iterator element type is `EdgeReference<E, Ty, Ix>`.
edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix>385     pub fn edges(&self, a: NodeIndex<Ix>) -> Edges<E, Ty, Ix> {
386         let r = self.neighbors_range(a);
387         Edges {
388             index: r.start,
389             source: a,
390             iter: zip(&self.column[r.clone()], &self.edges[r]),
391             ty: self.ty,
392         }
393     }
394 }
395 
396 #[derive(Clone, Debug)]
397 pub struct Edges<'a, E: 'a, Ty = Directed, Ix: 'a = DefaultIx> {
398     index: usize,
399     source: NodeIndex<Ix>,
400     iter: Zip<SliceIter<'a, NodeIndex<Ix>>, SliceIter<'a, E>>,
401     ty: PhantomData<Ty>,
402 }
403 
404 #[derive(Debug)]
405 pub struct EdgeReference<'a, E: 'a, Ty, Ix: 'a = DefaultIx> {
406     index: EdgeIndex,
407     source: NodeIndex<Ix>,
408     target: NodeIndex<Ix>,
409     weight: &'a E,
410     ty: PhantomData<Ty>,
411 }
412 
413 impl<'a, E, Ty, Ix: Copy> Clone for EdgeReference<'a, E, Ty, Ix> {
clone(&self) -> Self414     fn clone(&self) -> Self {
415         *self
416     }
417 }
418 
419 impl<'a, E, Ty, Ix: Copy> Copy for EdgeReference<'a, E, Ty, Ix> {}
420 
421 impl<'a, Ty, E, Ix> EdgeReference<'a, E, Ty, Ix>
422 where
423     Ty: EdgeType,
424 {
425     /// Access the edge’s weight.
426     ///
427     /// **NOTE** that this method offers a longer lifetime
428     /// than the trait (unfortunately they don't match yet).
weight(&self) -> &'a E429     pub fn weight(&self) -> &'a E {
430         self.weight
431     }
432 }
433 
434 impl<'a, E, Ty, Ix> EdgeRef for EdgeReference<'a, E, Ty, Ix>
435 where
436     Ty: EdgeType,
437     Ix: IndexType,
438 {
439     type NodeId = NodeIndex<Ix>;
440     type EdgeId = EdgeIndex;
441     type Weight = E;
442 
source(&self) -> Self::NodeId443     fn source(&self) -> Self::NodeId {
444         self.source
445     }
target(&self) -> Self::NodeId446     fn target(&self) -> Self::NodeId {
447         self.target
448     }
weight(&self) -> &E449     fn weight(&self) -> &E {
450         self.weight
451     }
id(&self) -> Self::EdgeId452     fn id(&self) -> Self::EdgeId {
453         self.index
454     }
455 }
456 
457 impl<'a, E, Ty, Ix> Iterator for Edges<'a, E, Ty, Ix>
458 where
459     Ty: EdgeType,
460     Ix: IndexType,
461 {
462     type Item = EdgeReference<'a, E, Ty, Ix>;
next(&mut self) -> Option<Self::Item>463     fn next(&mut self) -> Option<Self::Item> {
464         self.iter.next().map(move |(&j, w)| {
465             let index = self.index;
466             self.index += 1;
467             EdgeReference {
468                 index,
469                 source: self.source,
470                 target: j,
471                 weight: w,
472                 ty: PhantomData,
473             }
474         })
475     }
size_hint(&self) -> (usize, Option<usize>)476     fn size_hint(&self) -> (usize, Option<usize>) {
477         self.iter.size_hint()
478     }
479 }
480 
481 impl<N, E, Ty, Ix> Data for Csr<N, E, Ty, Ix>
482 where
483     Ty: EdgeType,
484     Ix: IndexType,
485 {
486     type NodeWeight = N;
487     type EdgeWeight = E;
488 }
489 
490 impl<'a, N, E, Ty, Ix> IntoEdgeReferences for &'a Csr<N, E, Ty, Ix>
491 where
492     Ty: EdgeType,
493     Ix: IndexType,
494 {
495     type EdgeRef = EdgeReference<'a, E, Ty, Ix>;
496     type EdgeReferences = EdgeReferences<'a, E, Ty, Ix>;
edge_references(self) -> Self::EdgeReferences497     fn edge_references(self) -> Self::EdgeReferences {
498         EdgeReferences {
499             index: 0,
500             source_index: Ix::new(0),
501             edge_ranges: self.row.windows(2).enumerate(),
502             column: &self.column,
503             edges: &self.edges,
504             iter: zip(&[], &[]),
505             ty: self.ty,
506         }
507     }
508 }
509 
510 #[derive(Debug, Clone)]
511 pub struct EdgeReferences<'a, E: 'a, Ty, Ix: 'a> {
512     source_index: NodeIndex<Ix>,
513     index: usize,
514     edge_ranges: Enumerate<Windows<'a, usize>>,
515     column: &'a [NodeIndex<Ix>],
516     edges: &'a [E],
517     iter: Zip<SliceIter<'a, NodeIndex<Ix>>, SliceIter<'a, E>>,
518     ty: PhantomData<Ty>,
519 }
520 
521 impl<'a, E, Ty, Ix> Iterator for EdgeReferences<'a, E, Ty, Ix>
522 where
523     Ty: EdgeType,
524     Ix: IndexType,
525 {
526     type Item = EdgeReference<'a, E, Ty, Ix>;
next(&mut self) -> Option<Self::Item>527     fn next(&mut self) -> Option<Self::Item> {
528         loop {
529             if let Some((&j, w)) = self.iter.next() {
530                 let index = self.index;
531                 self.index += 1;
532                 return Some(EdgeReference {
533                     index,
534                     source: self.source_index,
535                     target: j,
536                     weight: w,
537                     ty: PhantomData,
538                 });
539             }
540             if let Some((i, w)) = self.edge_ranges.next() {
541                 let a = w[0];
542                 let b = w[1];
543                 self.iter = zip(&self.column[a..b], &self.edges[a..b]);
544                 self.source_index = Ix::new(i);
545             } else {
546                 return None;
547             }
548         }
549     }
550 }
551 
552 impl<'a, N, E, Ty, Ix> IntoEdges for &'a Csr<N, E, Ty, Ix>
553 where
554     Ty: EdgeType,
555     Ix: IndexType,
556 {
557     type Edges = Edges<'a, E, Ty, Ix>;
edges(self, a: Self::NodeId) -> Self::Edges558     fn edges(self, a: Self::NodeId) -> Self::Edges {
559         self.edges(a)
560     }
561 }
562 
563 impl<N, E, Ty, Ix> GraphBase for Csr<N, E, Ty, Ix>
564 where
565     Ty: EdgeType,
566     Ix: IndexType,
567 {
568     type NodeId = NodeIndex<Ix>;
569     type EdgeId = EdgeIndex; // index into edges vector
570 }
571 
572 use fixedbitset::FixedBitSet;
573 
574 impl<N, E, Ty, Ix> Visitable for Csr<N, E, Ty, Ix>
575 where
576     Ty: EdgeType,
577     Ix: IndexType,
578 {
579     type Map = FixedBitSet;
visit_map(&self) -> FixedBitSet580     fn visit_map(&self) -> FixedBitSet {
581         FixedBitSet::with_capacity(self.node_count())
582     }
reset_map(&self, map: &mut Self::Map)583     fn reset_map(&self, map: &mut Self::Map) {
584         map.clear();
585         map.grow(self.node_count());
586     }
587 }
588 
589 use std::slice::Iter as SliceIter;
590 
591 #[derive(Clone, Debug)]
592 pub struct Neighbors<'a, Ix: 'a = DefaultIx> {
593     iter: SliceIter<'a, NodeIndex<Ix>>,
594 }
595 
596 impl<'a, Ix> Iterator for Neighbors<'a, Ix>
597 where
598     Ix: IndexType,
599 {
600     type Item = NodeIndex<Ix>;
601 
next(&mut self) -> Option<Self::Item>602     fn next(&mut self) -> Option<Self::Item> {
603         self.iter.next().cloned()
604     }
605 
size_hint(&self) -> (usize, Option<usize>)606     fn size_hint(&self) -> (usize, Option<usize>) {
607         self.iter.size_hint()
608     }
609 }
610 
611 impl<'a, N, E, Ty, Ix> IntoNeighbors for &'a Csr<N, E, Ty, Ix>
612 where
613     Ty: EdgeType,
614     Ix: IndexType,
615 {
616     type Neighbors = Neighbors<'a, Ix>;
617 
618     /// Return an iterator of all neighbors of `a`.
619     ///
620     /// - `Directed`: Targets of outgoing edges from `a`.
621     /// - `Undirected`: Opposing endpoints of all edges connected to `a`.
622     ///
623     /// **Panics** if the node `a` does not exist.<br>
624     /// Iterator element type is `NodeIndex<Ix>`.
neighbors(self, a: Self::NodeId) -> Self::Neighbors625     fn neighbors(self, a: Self::NodeId) -> Self::Neighbors {
626         Neighbors {
627             iter: self.neighbors_slice(a).iter(),
628         }
629     }
630 }
631 
632 impl<N, E, Ty, Ix> NodeIndexable for Csr<N, E, Ty, Ix>
633 where
634     Ty: EdgeType,
635     Ix: IndexType,
636 {
node_bound(&self) -> usize637     fn node_bound(&self) -> usize {
638         self.node_count()
639     }
to_index(&self, a: Self::NodeId) -> usize640     fn to_index(&self, a: Self::NodeId) -> usize {
641         a.index()
642     }
from_index(&self, ix: usize) -> Self::NodeId643     fn from_index(&self, ix: usize) -> Self::NodeId {
644         Ix::new(ix)
645     }
646 }
647 
648 impl<N, E, Ty, Ix> NodeCompactIndexable for Csr<N, E, Ty, Ix>
649 where
650     Ty: EdgeType,
651     Ix: IndexType,
652 {
653 }
654 
655 impl<N, E, Ty, Ix> Index<NodeIndex<Ix>> for Csr<N, E, Ty, Ix>
656 where
657     Ty: EdgeType,
658     Ix: IndexType,
659 {
660     type Output = N;
661 
index(&self, ix: NodeIndex<Ix>) -> &N662     fn index(&self, ix: NodeIndex<Ix>) -> &N {
663         &self.node_weights[ix.index()]
664     }
665 }
666 
667 impl<N, E, Ty, Ix> IndexMut<NodeIndex<Ix>> for Csr<N, E, Ty, Ix>
668 where
669     Ty: EdgeType,
670     Ix: IndexType,
671 {
index_mut(&mut self, ix: NodeIndex<Ix>) -> &mut N672     fn index_mut(&mut self, ix: NodeIndex<Ix>) -> &mut N {
673         &mut self.node_weights[ix.index()]
674     }
675 }
676 
677 #[derive(Debug, Clone)]
678 pub struct NodeIdentifiers<Ix = DefaultIx> {
679     r: Range<usize>,
680     ty: PhantomData<Ix>,
681 }
682 
683 impl<Ix> Iterator for NodeIdentifiers<Ix>
684 where
685     Ix: IndexType,
686 {
687     type Item = NodeIndex<Ix>;
688 
next(&mut self) -> Option<Self::Item>689     fn next(&mut self) -> Option<Self::Item> {
690         self.r.next().map(Ix::new)
691     }
692 
size_hint(&self) -> (usize, Option<usize>)693     fn size_hint(&self) -> (usize, Option<usize>) {
694         self.r.size_hint()
695     }
696 }
697 
698 impl<'a, N, E, Ty, Ix> IntoNodeIdentifiers for &'a Csr<N, E, Ty, Ix>
699 where
700     Ty: EdgeType,
701     Ix: IndexType,
702 {
703     type NodeIdentifiers = NodeIdentifiers<Ix>;
node_identifiers(self) -> Self::NodeIdentifiers704     fn node_identifiers(self) -> Self::NodeIdentifiers {
705         NodeIdentifiers {
706             r: 0..self.node_count(),
707             ty: PhantomData,
708         }
709     }
710 }
711 
712 impl<N, E, Ty, Ix> NodeCount for Csr<N, E, Ty, Ix>
713 where
714     Ty: EdgeType,
715     Ix: IndexType,
716 {
node_count(&self) -> usize717     fn node_count(&self) -> usize {
718         (*self).node_count()
719     }
720 }
721 
722 impl<N, E, Ty, Ix> EdgeCount for Csr<N, E, Ty, Ix>
723 where
724     Ty: EdgeType,
725     Ix: IndexType,
726 {
727     #[inline]
edge_count(&self) -> usize728     fn edge_count(&self) -> usize {
729         self.edge_count()
730     }
731 }
732 
733 impl<N, E, Ty, Ix> GraphProp for Csr<N, E, Ty, Ix>
734 where
735     Ty: EdgeType,
736     Ix: IndexType,
737 {
738     type EdgeType = Ty;
739 }
740 
741 impl<'a, N, E, Ty, Ix> IntoNodeReferences for &'a Csr<N, E, Ty, Ix>
742 where
743     Ty: EdgeType,
744     Ix: IndexType,
745 {
746     type NodeRef = (NodeIndex<Ix>, &'a N);
747     type NodeReferences = NodeReferences<'a, N, Ix>;
node_references(self) -> Self::NodeReferences748     fn node_references(self) -> Self::NodeReferences {
749         NodeReferences {
750             iter: self.node_weights.iter().enumerate(),
751             ty: PhantomData,
752         }
753     }
754 }
755 
756 /// Iterator over all nodes of a graph.
757 #[derive(Debug, Clone)]
758 pub struct NodeReferences<'a, N: 'a, Ix: IndexType = DefaultIx> {
759     iter: Enumerate<SliceIter<'a, N>>,
760     ty: PhantomData<Ix>,
761 }
762 
763 impl<'a, N, Ix> Iterator for NodeReferences<'a, N, Ix>
764 where
765     Ix: IndexType,
766 {
767     type Item = (NodeIndex<Ix>, &'a N);
768 
next(&mut self) -> Option<Self::Item>769     fn next(&mut self) -> Option<Self::Item> {
770         self.iter.next().map(|(i, weight)| (Ix::new(i), weight))
771     }
772 
size_hint(&self) -> (usize, Option<usize>)773     fn size_hint(&self) -> (usize, Option<usize>) {
774         self.iter.size_hint()
775     }
776 }
777 
778 impl<'a, N, Ix> DoubleEndedIterator for NodeReferences<'a, N, Ix>
779 where
780     Ix: IndexType,
781 {
next_back(&mut self) -> Option<Self::Item>782     fn next_back(&mut self) -> Option<Self::Item> {
783         self.iter
784             .next_back()
785             .map(|(i, weight)| (Ix::new(i), weight))
786     }
787 }
788 
789 impl<'a, N, Ix> ExactSizeIterator for NodeReferences<'a, N, Ix> where Ix: IndexType {}
790 
791 /// The adjacency matrix for **Csr** is a bitmap that's computed by
792 /// `.adjacency_matrix()`.
793 impl<'a, N, E, Ty, Ix> GetAdjacencyMatrix for &'a Csr<N, E, Ty, Ix>
794 where
795     Ix: IndexType,
796     Ty: EdgeType,
797 {
798     type AdjMatrix = FixedBitSet;
799 
adjacency_matrix(&self) -> FixedBitSet800     fn adjacency_matrix(&self) -> FixedBitSet {
801         let n = self.node_count();
802         let mut matrix = FixedBitSet::with_capacity(n * n);
803         for edge in self.edge_references() {
804             let i = edge.source().index() * n + edge.target().index();
805             matrix.put(i);
806 
807             let j = edge.source().index() + n * edge.target().index();
808             matrix.put(j);
809         }
810         matrix
811     }
812 
is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool813     fn is_adjacent(&self, matrix: &FixedBitSet, a: NodeIndex<Ix>, b: NodeIndex<Ix>) -> bool {
814         let n = self.edge_count();
815         let index = n * a.index() + b.index();
816         matrix.contains(index)
817     }
818 }
819 
820 /*
821  *
822 Example
823 
824 [ a 0 b
825   c d e
826   0 0 f ]
827 
828 Values: [a, b, c, d, e, f]
829 Column: [0, 2, 0, 1, 2, 2]
830 Row   : [0, 2, 5]   <- value index of row start
831 
832  * */
833 
834 #[cfg(test)]
835 mod tests {
836     use super::Csr;
837     use crate::algo::bellman_ford;
838     use crate::algo::find_negative_cycle;
839     use crate::algo::tarjan_scc;
840     use crate::visit::Dfs;
841     use crate::visit::VisitMap;
842     use crate::Undirected;
843 
844     #[test]
csr1()845     fn csr1() {
846         let mut m: Csr = Csr::with_nodes(3);
847         m.add_edge(0, 0, ());
848         m.add_edge(1, 2, ());
849         m.add_edge(2, 2, ());
850         m.add_edge(0, 2, ());
851         m.add_edge(1, 0, ());
852         m.add_edge(1, 1, ());
853         println!("{:?}", m);
854         assert_eq!(&m.column, &[0, 2, 0, 1, 2, 2]);
855         assert_eq!(&m.row, &[0, 2, 5, 6]);
856 
857         let added = m.add_edge(1, 2, ());
858         assert!(!added);
859         assert_eq!(&m.column, &[0, 2, 0, 1, 2, 2]);
860         assert_eq!(&m.row, &[0, 2, 5, 6]);
861 
862         assert_eq!(m.neighbors_slice(1), &[0, 1, 2]);
863         assert_eq!(m.node_count(), 3);
864         assert_eq!(m.edge_count(), 6);
865     }
866 
867     #[test]
csr_undirected()868     fn csr_undirected() {
869         /*
870            [ 1 . 1
871              . . 1
872              1 1 1 ]
873         */
874 
875         let mut m: Csr<(), (), Undirected> = Csr::with_nodes(3);
876         m.add_edge(0, 0, ());
877         m.add_edge(0, 2, ());
878         m.add_edge(1, 2, ());
879         m.add_edge(2, 2, ());
880         println!("{:?}", m);
881         assert_eq!(&m.column, &[0, 2, 2, 0, 1, 2]);
882         assert_eq!(&m.row, &[0, 2, 3, 6]);
883         assert_eq!(m.node_count(), 3);
884         assert_eq!(m.edge_count(), 4);
885     }
886 
887     #[should_panic]
888     #[test]
csr_from_error_1()889     fn csr_from_error_1() {
890         // not sorted in source
891         let m: Csr = Csr::from_sorted_edges(&[(0, 1), (1, 0), (0, 2)]).unwrap();
892         println!("{:?}", m);
893     }
894 
895     #[should_panic]
896     #[test]
csr_from_error_2()897     fn csr_from_error_2() {
898         // not sorted in target
899         let m: Csr = Csr::from_sorted_edges(&[(0, 1), (1, 0), (1, 2), (1, 1)]).unwrap();
900         println!("{:?}", m);
901     }
902 
903     #[test]
csr_from()904     fn csr_from() {
905         let m: Csr =
906             Csr::from_sorted_edges(&[(0, 1), (0, 2), (1, 0), (1, 1), (2, 2), (2, 4)]).unwrap();
907         println!("{:?}", m);
908         assert_eq!(m.neighbors_slice(0), &[1, 2]);
909         assert_eq!(m.neighbors_slice(1), &[0, 1]);
910         assert_eq!(m.neighbors_slice(2), &[2, 4]);
911         assert_eq!(m.node_count(), 5);
912         assert_eq!(m.edge_count(), 6);
913     }
914 
915     #[test]
csr_dfs()916     fn csr_dfs() {
917         let mut m: Csr = Csr::from_sorted_edges(&[
918             (0, 1),
919             (0, 2),
920             (1, 0),
921             (1, 1),
922             (1, 3),
923             (2, 2),
924             // disconnected subgraph
925             (4, 4),
926             (4, 5),
927         ])
928         .unwrap();
929         println!("{:?}", m);
930         let mut dfs = Dfs::new(&m, 0);
931         while let Some(_) = dfs.next(&m) {}
932         for i in 0..m.node_count() - 2 {
933             assert!(dfs.discovered.is_visited(&i), "visited {}", i)
934         }
935         assert!(!dfs.discovered[4]);
936         assert!(!dfs.discovered[5]);
937 
938         m.add_edge(1, 4, ());
939         println!("{:?}", m);
940 
941         dfs.reset(&m);
942         dfs.move_to(0);
943         while let Some(_) = dfs.next(&m) {}
944 
945         for i in 0..m.node_count() {
946             assert!(dfs.discovered[i], "visited {}", i)
947         }
948     }
949 
950     #[test]
csr_tarjan()951     fn csr_tarjan() {
952         let m: Csr = Csr::from_sorted_edges(&[
953             (0, 1),
954             (0, 2),
955             (1, 0),
956             (1, 1),
957             (1, 3),
958             (2, 2),
959             (2, 4),
960             (4, 4),
961             (4, 5),
962             (5, 2),
963         ])
964         .unwrap();
965         println!("{:?}", m);
966         println!("{:?}", tarjan_scc(&m));
967     }
968 
969     #[test]
test_bellman_ford()970     fn test_bellman_ford() {
971         let m: Csr<(), _> = Csr::from_sorted_edges(&[
972             (0, 1, 0.5),
973             (0, 2, 2.),
974             (1, 0, 1.),
975             (1, 1, 1.),
976             (1, 2, 1.),
977             (1, 3, 1.),
978             (2, 3, 3.),
979             (4, 5, 1.),
980             (5, 7, 2.),
981             (6, 7, 1.),
982             (7, 8, 3.),
983         ])
984         .unwrap();
985         println!("{:?}", m);
986         let result = bellman_ford(&m, 0).unwrap();
987         println!("{:?}", result);
988         let answer = [0., 0.5, 1.5, 1.5];
989         assert_eq!(&answer, &result.distances[..4]);
990         assert!(result.distances[4..].iter().all(|&x| f64::is_infinite(x)));
991     }
992 
993     #[test]
test_bellman_ford_neg_cycle()994     fn test_bellman_ford_neg_cycle() {
995         let m: Csr<(), _> = Csr::from_sorted_edges(&[
996             (0, 1, 0.5),
997             (0, 2, 2.),
998             (1, 0, 1.),
999             (1, 1, -1.),
1000             (1, 2, 1.),
1001             (1, 3, 1.),
1002             (2, 3, 3.),
1003         ])
1004         .unwrap();
1005         let result = bellman_ford(&m, 0);
1006         assert!(result.is_err());
1007     }
1008 
1009     #[test]
test_find_neg_cycle1()1010     fn test_find_neg_cycle1() {
1011         let m: Csr<(), _> = Csr::from_sorted_edges(&[
1012             (0, 1, 0.5),
1013             (0, 2, 2.),
1014             (1, 0, 1.),
1015             (1, 1, -1.),
1016             (1, 2, 1.),
1017             (1, 3, 1.),
1018             (2, 3, 3.),
1019         ])
1020         .unwrap();
1021         let result = find_negative_cycle(&m, 0);
1022         assert_eq!(result, Some([1].to_vec()));
1023     }
1024 
1025     #[test]
test_find_neg_cycle2()1026     fn test_find_neg_cycle2() {
1027         let m: Csr<(), _> = Csr::from_sorted_edges(&[
1028             (0, 1, 0.5),
1029             (0, 2, 2.),
1030             (1, 0, 1.),
1031             (1, 2, 1.),
1032             (1, 3, 1.),
1033             (2, 3, 3.),
1034         ])
1035         .unwrap();
1036         let result = find_negative_cycle(&m, 0);
1037         assert_eq!(result, None);
1038     }
1039 
1040     #[test]
test_find_neg_cycle3()1041     fn test_find_neg_cycle3() {
1042         let m: Csr<(), _> = Csr::from_sorted_edges(&[
1043             (0, 1, 1.),
1044             (0, 2, 1.),
1045             (0, 3, 1.),
1046             (1, 3, 1.),
1047             (2, 1, 1.),
1048             (3, 2, -3.),
1049         ])
1050         .unwrap();
1051         let result = find_negative_cycle(&m, 0);
1052         assert_eq!(result, Some([1, 3, 2].to_vec()));
1053     }
1054 
1055     #[test]
test_find_neg_cycle4()1056     fn test_find_neg_cycle4() {
1057         let m: Csr<(), _> = Csr::from_sorted_edges(&[(0, 0, -1.)]).unwrap();
1058         let result = find_negative_cycle(&m, 0);
1059         assert_eq!(result, Some([0].to_vec()));
1060     }
1061 
1062     #[test]
test_edge_references()1063     fn test_edge_references() {
1064         use crate::visit::EdgeRef;
1065         use crate::visit::IntoEdgeReferences;
1066         let m: Csr<(), _> = Csr::from_sorted_edges(&[
1067             (0, 1, 0.5),
1068             (0, 2, 2.),
1069             (1, 0, 1.),
1070             (1, 1, 1.),
1071             (1, 2, 1.),
1072             (1, 3, 1.),
1073             (2, 3, 3.),
1074             (4, 5, 1.),
1075             (5, 7, 2.),
1076             (6, 7, 1.),
1077             (7, 8, 3.),
1078         ])
1079         .unwrap();
1080         let mut copy = Vec::new();
1081         for e in m.edge_references() {
1082             copy.push((e.source(), e.target(), *e.weight()));
1083             println!("{:?}", e);
1084         }
1085         let m2: Csr<(), _> = Csr::from_sorted_edges(&copy).unwrap();
1086         assert_eq!(&m.row, &m2.row);
1087         assert_eq!(&m.column, &m2.column);
1088         assert_eq!(&m.edges, &m2.edges);
1089     }
1090 
1091     #[test]
test_add_node()1092     fn test_add_node() {
1093         let mut g: Csr = Csr::new();
1094         let a = g.add_node(());
1095         let b = g.add_node(());
1096         let c = g.add_node(());
1097 
1098         assert!(g.add_edge(a, b, ()));
1099         assert!(g.add_edge(b, c, ()));
1100         assert!(g.add_edge(c, a, ()));
1101 
1102         println!("{:?}", g);
1103 
1104         assert_eq!(g.node_count(), 3);
1105 
1106         assert_eq!(g.neighbors_slice(a), &[b]);
1107         assert_eq!(g.neighbors_slice(b), &[c]);
1108         assert_eq!(g.neighbors_slice(c), &[a]);
1109 
1110         assert_eq!(g.edge_count(), 3);
1111     }
1112 
1113     #[test]
test_add_node_with_existing_edges()1114     fn test_add_node_with_existing_edges() {
1115         let mut g: Csr = Csr::new();
1116         let a = g.add_node(());
1117         let b = g.add_node(());
1118 
1119         assert!(g.add_edge(a, b, ()));
1120 
1121         let c = g.add_node(());
1122 
1123         println!("{:?}", g);
1124 
1125         assert_eq!(g.node_count(), 3);
1126 
1127         assert_eq!(g.neighbors_slice(a), &[b]);
1128         assert_eq!(g.neighbors_slice(b), &[]);
1129         assert_eq!(g.neighbors_slice(c), &[]);
1130 
1131         assert_eq!(g.edge_count(), 1);
1132     }
1133 
1134     #[test]
test_node_references()1135     fn test_node_references() {
1136         use crate::visit::IntoNodeReferences;
1137         let mut g: Csr<u32> = Csr::new();
1138         g.add_node(42);
1139         g.add_node(3);
1140         g.add_node(44);
1141 
1142         let mut refs = g.node_references();
1143         assert_eq!(refs.next(), Some((0, &42)));
1144         assert_eq!(refs.next(), Some((1, &3)));
1145         assert_eq!(refs.next(), Some((2, &44)));
1146         assert_eq!(refs.next(), None);
1147     }
1148 }
1149