use leiden_rs::resolution::resolution_scan;
use leiden_rs::{GraphDataBuilder, Leiden, LeidenConfig, QualityType};
fn main() {
println!("=== Parallel vs Sequential Equivalence Test ===");
println!("\nTest 1: Small graph - sequential path (50 nodes, 100 edges)");
let mut b1 = GraphDataBuilder::new(50);
let mut edge_count = 0;
for u in 0..50 {
for v in (u + 1)..50 {
if edge_count < 100 {
b1.add_edge(u, v, 1.0).unwrap();
edge_count += 1;
}
}
}
let small_graph = b1.build().unwrap();
let leiden_small = Leiden::new(LeidenConfig {
seed: Some(42),
resolution: 1.0,
quality: QualityType::Modularity,
..Default::default()
});
let result_small = leiden_small.run(&small_graph).unwrap();
println!("✓ PASS: Small graph runs (sequential path)");
println!(
" Communities: {}, Quality: {:.4}",
result_small.partition.num_communities(),
result_small.quality
);
println!("\nTest 2: Medium graph - parallel path (200 nodes, 2500 edges)");
let mut b2 = GraphDataBuilder::new(200);
let mut edge_count = 0;
for u in 0..200 {
for v in (u + 1)..200 {
if edge_count < 2500 {
b2.add_edge(u, v, 1.0).unwrap();
edge_count += 1;
}
}
}
let medium_graph = b2.build().unwrap();
let leiden_medium = Leiden::new(LeidenConfig {
seed: Some(42),
resolution: 1.0,
quality: QualityType::Modularity,
..Default::default()
});
let result_medium = leiden_medium.run(&medium_graph).unwrap();
println!("✓ PASS: Medium graph runs (parallel path)");
println!(
" Communities: {}, Quality: {:.4}",
result_medium.partition.num_communities(),
result_medium.quality
);
println!("\nTest 3: Large graph - parallel + aggregation (400 nodes, 12000 edges)");
let mut b3 = GraphDataBuilder::new(400);
let mut edge_count = 0;
for u in 0..400 {
for v in (u + 1)..400 {
if edge_count < 12000 {
b3.add_edge(u, v, 1.0).unwrap();
edge_count += 1;
}
}
}
let large_graph = b3.build().unwrap();
let leiden_large = Leiden::new(LeidenConfig {
seed: Some(42),
resolution: 1.0,
quality: QualityType::Modularity,
..Default::default()
});
let result_large = leiden_large.run(&large_graph).unwrap();
println!("✓ PASS: Large graph runs (parallel + aggregation)");
println!(
" Communities: {}, Quality: {:.4}",
result_large.partition.num_communities(),
result_large.quality
);
println!("\nTest 4: Resolution scan with parallel execution");
let scan_results = resolution_scan(
&medium_graph,
QualityType::Modularity,
(0.1, 2.0),
5,
Some(42),
)
.unwrap();
println!("✓ PASS: Resolution scan completed");
println!(" Generated {} profile entries", scan_results.len());
for (i, entry) in scan_results.iter().enumerate() {
println!(
" Entry {}: gamma={:.2}, communities={}, quality={:.4}",
i, entry.resolution, entry.num_communities, entry.quality
);
}
println!("\nTest 5: Reproducibility - same seed on medium graph");
let leiden_repeat = Leiden::new(LeidenConfig {
seed: Some(42),
resolution: 1.0,
quality: QualityType::Modularity,
..Default::default()
});
let result_repeat = leiden_repeat.run(&medium_graph).unwrap();
let p1 = result_medium.partition.as_slice();
let p2 = result_repeat.partition.as_slice();
if p1 == p2 {
println!("✓ PASS: Reproducibility maintained");
println!(
" Communities: {}, Quality: {:.4}",
result_repeat.partition.num_communities(),
result_repeat.quality
);
} else {
println!("✗ FAIL: Same seed produced different results!");
std::process::exit(1);
}
println!("\n=== All parallel/sequential tests PASSED ===");
}