pub mod betweenness;
pub mod bfs;
pub mod community;
pub mod label_propagation;
pub mod pagerank;
pub mod scc;
pub mod sssp;
pub mod triangle;
pub mod wcc;
pub use betweenness::{Between, betweenness, betweenness_exact, betweenness_with};
pub use bfs::{UNREACHED, bfs};
pub use community::{leiden, leiden_with, louvain, louvain_with, modularity, modularity_with};
pub use label_propagation::{label_propagation, label_propagation_with};
pub use pagerank::{Rank, pagerank, pagerank_with};
pub use scc::scc;
pub use sssp::{UNREACHABLE, sssp, sssp_with};
pub use triangle::triangle_count;
pub use wcc::wcc;
#[derive(Debug, Clone)]
pub struct Components {
of: Vec<u32>,
count: u32,
}
impl Components {
#[must_use]
pub fn of(&self, node: u32) -> u32 {
self.of[node as usize]
}
#[must_use]
pub fn same(&self, a: u32, b: u32) -> bool {
self.of(a) == self.of(b)
}
#[must_use]
pub fn count(&self) -> u32 {
self.count
}
#[must_use]
pub fn len(&self) -> u32 {
self.of.len() as u32
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.of.is_empty()
}
#[must_use]
pub fn largest(&self) -> Option<(u32, u32)> {
let mut size = vec![0u32; self.of.len()];
for c in &self.of {
size[*c as usize] += 1;
}
size.iter()
.enumerate()
.filter(|(_, n)| **n > 0)
.max_by_key(|(at, n)| (**n, std::cmp::Reverse(*at)))
.map(|(at, n)| (at as u32, *n))
}
#[must_use]
pub fn labels(&self) -> &[u32] {
&self.of
}
}
pub(crate) fn tidy(mut of: Vec<u32>) -> Components {
let mut low = vec![u32::MAX; of.len()];
for (node, at) in of.iter().enumerate() {
let low = &mut low[*at as usize];
*low = (*low).min(node as u32);
}
let count = low.iter().filter(|low| **low != u32::MAX).count() as u32;
for at in &mut of {
*at = low[*at as usize];
}
Components { of, count }
}
#[derive(Debug, Clone)]
pub(crate) struct Bits {
words: Vec<u64>,
len: u32,
}
impl Bits {
pub(crate) fn new(len: u32) -> Bits {
Bits {
words: vec![0; (len as usize).div_ceil(64)],
len,
}
}
pub(crate) fn clear(&mut self) {
self.words.fill(0);
}
#[inline]
pub(crate) fn set(&mut self, at: u32) {
self.words[at as usize / 64] |= 1 << (at % 64);
}
#[inline]
pub(crate) fn unset(&mut self, at: u32) {
self.words[at as usize / 64] &= !(1 << (at % 64));
}
#[inline]
pub(crate) fn get(&self, at: u32) -> bool {
self.words[at as usize / 64] >> (at % 64) & 1 == 1
}
pub(crate) fn for_each(&self, mut f: impl FnMut(u32)) {
for (i, word) in self.words.iter().enumerate() {
let mut w = *word;
while w != 0 {
let at = i as u32 * 64 + w.trailing_zeros();
if at >= self.len {
return;
}
f(at);
w &= w - 1;
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_bitmap_holds_what_was_put_in_it() {
let mut b = Bits::new(200);
for at in [0u32, 1, 63, 64, 65, 199] {
b.set(at);
}
assert!(b.get(64));
assert!(!b.get(66));
let mut seen = Vec::new();
b.for_each(|at| seen.push(at));
assert_eq!(seen, vec![0, 1, 63, 64, 65, 199]);
b.clear();
assert!(!b.get(0));
assert!(!b.get(199));
}
#[test]
fn a_bit_past_the_end_is_not_a_node() {
let mut b = Bits::new(3);
b.set(0);
b.set(2);
b.words[0] |= 1 << 40;
let mut seen = Vec::new();
b.for_each(|at| seen.push(at));
assert_eq!(seen, vec![0, 2]);
}
}