in src/dachshund/algorithms/betweenness.rs [54:93]
fn get_node_betweenness_brandes(&self) -> Result<HashMap<NodeId, f64>, &'static str> {
// Algorithm: Brandes, Ulrik. A Faster Algorithm For Betweeness Centrality.
// https://www.eecs.wsu.edu/~assefaw/CptS580-06/papers/brandes01centrality.pdf
if self.count_nodes() == 0 {
return Err("Graph is empty");
}
if !self.get_is_connected().unwrap() {
return Err("Graph should be connected to compute betweenness.");
}
let mut betweenness: HashMap<NodeId, f64> = HashMap::new();
for node_id in self.get_ids_iter() {
betweenness.insert(*node_id, 0.0);
}
for source in self.get_ids_iter() {
let (mut stack, shortest_path_counts, preds) = self.get_shortest_paths_bfs(*source);
let mut dependencies: HashMap<NodeId, f64> = HashMap::new();
for node_id in self.get_ids_iter() {
dependencies.insert(*node_id, 0.0);
}
// Process nodes in order of nonincreasing distance from source to leverage
// recurrence relation in accumulating pair dependencies.
while !stack.is_empty() {
let w = stack.pop().unwrap();
for pred in &preds[&w] {
*dependencies.entry(*pred).or_insert(0.0) += (0.5 + dependencies[&w])
* (shortest_path_counts[&pred] as f64 / shortest_path_counts[&w] as f64)
}
if w != *source {
*betweenness.entry(w).or_insert(0.0) += dependencies[&w]
}
}
}
Ok(betweenness)
}