MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / run

Function run

nodedb/src/engine/graph/algo/betweenness.rs:25–83  ·  view source on GitHub ↗

Run Betweenness Centrality on the CSR index. `params.sample_size`: if set, only sample that many source nodes (approximate). If `None`, compute exact centrality (all sources). Returns `(node_id, centrality)` sorted by centrality descending.

(csr: &CsrIndex, params: &AlgoParams)

Source from the content-addressed store, hash-verified

23///
24/// Returns `(node_id, centrality)` sorted by centrality descending.
25pub fn run(csr: &CsrIndex, params: &AlgoParams) -> AlgoResultBatch {
26 let n = csr.node_count();
27 if n == 0 {
28 return AlgoResultBatch::new(GraphAlgorithm::Betweenness);
29 }
30
31 let mut cb = vec![0.0f64; n];
32
33 // Determine source nodes: all or sampled subset.
34 let sources: Vec<usize> = match params.sample_size {
35 Some(sample) if sample < n => {
36 // Deterministic sampling via LCG.
37 let mut state: u64 = (n as u64).wrapping_mul(0x517cc1b727220a95).wrapping_add(1);
38 let mut selected = Vec::with_capacity(sample);
39 let mut used = vec![false; n];
40 while selected.len() < sample {
41 state = state
42 .wrapping_mul(6_364_136_223_846_793_005)
43 .wrapping_add(1);
44 let idx = (state >> 33) as usize % n;
45 if !used[idx] {
46 used[idx] = true;
47 selected.push(idx);
48 }
49 }
50 selected
51 }
52 _ => (0..n).collect(),
53 };
54
55 let scale = if params.sample_size.is_some() && sources.len() < n {
56 // Scale approximate centrality to estimate full centrality.
57 n as f64 / sources.len() as f64
58 } else {
59 1.0
60 };
61
62 // Brandes' algorithm: BFS from each source, then reverse accumulation.
63 for &s in &sources {
64 brandes_from_source(csr, s, n, &mut cb);
65 }
66
67 // Scale and normalize.
68 if scale != 1.0 {
69 for c in cb.iter_mut() {
70 *c *= scale;
71 }
72 }
73
74 // Build result sorted by centrality descending.
75 let mut scored: Vec<(usize, f64)> = cb.into_iter().enumerate().collect();
76 scored.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
77
78 let mut batch = AlgoResultBatch::new(GraphAlgorithm::Betweenness);
79 for (node, centrality) in scored {
80 batch.push_node_f64(csr.node_name_raw(node as u32).to_string(), centrality);
81 }
82 batch

Callers 4

betweenness_path_graphFunction · 0.70
betweenness_triangleFunction · 0.70
betweenness_starFunction · 0.70

Calls 10

brandes_from_sourceFunction · 0.85
collectMethod · 0.80
iter_mutMethod · 0.80
push_node_f64Method · 0.80
to_stringMethod · 0.80
node_countMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45
partial_cmpMethod · 0.45
node_name_rawMethod · 0.45

Tested by 4

betweenness_path_graphFunction · 0.56
betweenness_triangleFunction · 0.56
betweenness_starFunction · 0.56