Skip to content

Commit 25ea6eb

Browse files
committed
Fixed inconsistencies with NetworkX's implementation.
1 parent f4b2d45 commit 25ea6eb

1 file changed

Lines changed: 39 additions & 62 deletions

File tree

src/algorithms/centrality/groups/betweenness.rs

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -454,20 +454,19 @@ where
454454
while let Some(v) = queue.pop_front() {
455455
s_stack.push(v);
456456

457-
if let Ok(neighbors) = graph.get_successor_nodes(all_nodes[v].clone()) {
458-
for neighbor in neighbors {
459-
if let Some(&w) = node_to_index.get(&neighbor.name) {
460-
// First time we see w?
461-
if d[w] < 0.0 {
462-
queue.push_back(w);
463-
d[w] = d[v] + 1.0;
464-
}
457+
let neighbors = graph.get_successors_or_neighbors(all_nodes[v].clone());
458+
for neighbor in neighbors {
459+
if let Some(&w) = node_to_index.get(&neighbor.name) {
460+
// First time we see w?
461+
if d[w] < 0.0 {
462+
queue.push_back(w);
463+
d[w] = d[v] + 1.0;
464+
}
465465

466-
// Shortest path to w via v?
467-
if (d[w] - d[v] - 1.0_f64).abs() < 1e-10_f64 {
468-
sigma[w] += sigma[v];
469-
p[w].push(v);
470-
}
466+
// Shortest path to w via v?
467+
if (d[w] - d[v] - 1.0_f64).abs() < 1e-10_f64 {
468+
sigma[w] += sigma[v];
469+
p[w].push(v);
471470
}
472471
}
473472
}
@@ -529,35 +528,33 @@ where
529528
continue;
530529
}
531530

532-
if let Ok(successors) = graph.get_successor_nodes(all_nodes[v].clone()) {
533-
for successor in successors {
534-
if let Some(&w) = node_to_index.get(&successor.name) {
535-
// Get edge weight - extract from the edge's weight field
536-
let weight = match graph.get_edge(all_nodes[v].clone(), all_nodes[w].clone()) {
537-
Ok(edge) => edge.weight,
538-
Err(_) => 1.0, // Default weight if edge not found
539-
};
540-
541-
let new_dist = d[v] + weight;
542-
543-
// First time seeing this node or found a shorter path
544-
if d[w] == f64::INFINITY {
545-
d[w] = new_dist;
546-
sigma[w] = sigma[v];
547-
p[w].push(v);
548-
queue.push((OrderedFloat(new_dist), w));
549-
} else if (new_dist - d[w]).abs() < 1e-10 {
550-
// Found another shortest path of same length
551-
sigma[w] += sigma[v];
552-
p[w].push(v);
553-
} else if new_dist < d[w] {
554-
// Found a strictly shorter path
555-
d[w] = new_dist;
556-
sigma[w] = sigma[v];
557-
p[w].clear();
558-
p[w].push(v);
559-
queue.push((OrderedFloat(new_dist), w));
560-
}
531+
let successors = graph.get_successors_or_neighbors(all_nodes[v].clone());
532+
for successor in successors {
533+
if let Some(&w) = node_to_index.get(&successor.name) {
534+
// Get edge weight - extract from the edge's weight field
535+
let weight = match graph.get_edge(all_nodes[v].clone(), all_nodes[w].clone()) {
536+
Ok(edge) => edge.weight,
537+
Err(_) => 1.0, // Default weight if edge not found
538+
};
539+
let new_dist = d[v] + weight;
540+
541+
// First time seeing this node or found a shorter path
542+
if d[w] == f64::INFINITY {
543+
d[w] = new_dist;
544+
sigma[w] = sigma[v];
545+
p[w].push(v);
546+
queue.push((OrderedFloat(new_dist), w));
547+
} else if (new_dist - d[w]).abs() < 1e-10 {
548+
// Found another shortest path of same length
549+
sigma[w] += sigma[v];
550+
p[w].push(v);
551+
} else if new_dist < d[w] {
552+
// Found a strictly shorter path
553+
d[w] = new_dist;
554+
sigma[w] = sigma[v];
555+
p[w].clear();
556+
p[w].push(v);
557+
queue.push((OrderedFloat(new_dist), w));
561558
}
562559
}
563560
}
@@ -748,10 +745,6 @@ mod networkx_compatibility_tests {
748745
}
749746

750747
let result = group_betweenness_centrality(&graph, &group, true, false, false).unwrap();
751-
println!(
752-
"Group {:?}: graphrs={}, networkx={}",
753-
group_nodes, result, expected
754-
);
755748

756749
// Allow small floating point differences
757750
assert!(
@@ -784,10 +777,6 @@ mod networkx_compatibility_tests {
784777
}
785778

786779
let result = group_betweenness_centrality(&graph, &group, true, false, false).unwrap();
787-
println!(
788-
"Karate Club Group {:?}: graphrs={}, networkx={}",
789-
group_nodes, result, expected
790-
);
791780

792781
// Allow small floating point differences
793782
assert!(
@@ -817,7 +806,6 @@ mod networkx_compatibility_tests {
817806
let result = group_betweenness_centrality(&graph, &group, true, false, false).unwrap();
818807
let expected = 0.0; // NetworkX result
819808

820-
println!("K4 Group {{1}}: graphrs={}, networkx={}", result, expected);
821809
assert!((result - expected).abs() < 1e-10);
822810
}
823811

@@ -836,10 +824,6 @@ mod networkx_compatibility_tests {
836824
let result = group_betweenness_centrality(&graph, &group, true, false, false).unwrap();
837825
let expected = 1.0; // NetworkX result
838826

839-
println!(
840-
"Star Group {{0}} (center): graphrs={}, networkx={}",
841-
result, expected
842-
);
843827
assert!((result - expected).abs() < 1e-10);
844828

845829
// Test leaf nodes
@@ -849,10 +833,6 @@ mod networkx_compatibility_tests {
849833
let result = group_betweenness_centrality(&graph, &group, true, false, false).unwrap();
850834
let expected = 0.0; // NetworkX result
851835

852-
println!(
853-
"Star Group {{1,2}} (leaves): graphrs={}, networkx={}",
854-
result, expected
855-
);
856836
assert!((result - expected).abs() < 1e-10);
857837
}
858838

@@ -878,9 +858,6 @@ mod networkx_compatibility_tests {
878858
let weighted_result =
879859
group_betweenness_centrality(&graph, &group, true, false, true).unwrap();
880860

881-
println!("Unweighted result: {}", unweighted_result);
882-
println!("Weighted result: {}", weighted_result);
883-
884861
// The results should be different because weighted paths will prefer 0->3 directly
885862
// while unweighted will treat all edges equally
886863
assert!(

0 commit comments

Comments
 (0)