use scirs2_graph::{Hypergraph, Result};
#[allow(dead_code)]
fn main() -> Result<()> {
println!("=== Hypergraph Demo ===\n");
let mut hypergraph: Hypergraph<&str, f64> = Hypergraph::new();
println!("1. Creating hypergraph and adding nodes:");
hypergraph.add_node("Alice");
hypergraph.add_node("Bob");
hypergraph.add_node("Charlie");
hypergraph.add_node("Diana");
hypergraph.add_node("Eve");
println!(
" Initial nodes: {:?}",
hypergraph.nodes().collect::<Vec<_>>()
);
println!(" Node count: {}", hypergraph.node_count());
println!("\n2. Adding hyperedges:");
let he1 = hypergraph.add_hyperedge_from_vec(vec!["Alice", "Bob", "Charlie"], 1.0)?;
println!(" Added collaboration hyperedge {he1}: Alice-Bob-Charlie (weight: 1.0)");
let he2 = hypergraph.add_hyperedge_from_vec(vec!["Alice", "Diana"], 0.8)?;
println!(" Added friendship hyperedge {he2}: Alice-Diana (weight: 0.8)");
let he3 = hypergraph.add_hyperedge_from_vec(vec!["Bob", "Charlie", "Diana", "Eve"], 1.5)?;
println!(" Added meeting hyperedge {he3}: Bob-Charlie-Diana-Eve (weight: 1.5)");
println!("\n3. Hypergraph statistics:");
println!(" Total nodes: {}", hypergraph.node_count());
println!(" Total hyperedges: {}", hypergraph.hyperedge_count());
let (min_size, max_size, avg_size) = hypergraph.hyperedge_size_stats();
println!(" Hyperedge sizes - Min: {min_size}, Max: {max_size}, Avg: {avg_size:.2}");
println!(" Is uniform: {}", hypergraph.is_uniform());
println!("\n4. Analyzing connections:");
for person in &["Alice", "Bob", "Charlie", "Diana", "Eve"] {
let neighbors = hypergraph.neighbors(person);
let degree = hypergraph.degree(person);
println!(
" {}: degree = {}, neighbors = {:?}",
person,
degree,
neighbors.iter().collect::<Vec<_>>()
);
}
println!("\n5. Connectivity analysis:");
let pairs = [("Alice", "Bob"), ("Alice", "Eve"), ("Diana", "Charlie")];
for (person1, person2) in pairs.iter() {
let connected = hypergraph.are_connected(person1, person2);
let connecting_edges = hypergraph.connecting_hyperedges(person1, person2);
println!(
" {person1} and {person2} connected: {connected} (via hyperedges: {connecting_edges:?})"
);
}
println!("\n6. Hyperedge details:");
for hyperedge in hypergraph.hyperedges() {
println!(
" Hyperedge {}: nodes = {:?}, weight = {}, size = {}",
hyperedge.id,
hyperedge.nodes.iter().collect::<Vec<_>>(),
hyperedge.weight,
hyperedge.nodes.len()
);
}
println!("\n7. Converting to regular graph (2-section):");
let regular_graph = hypergraph.to_graph();
println!(" Regular graph nodes: {}", regular_graph.node_count());
println!(" Regular graph edges: {}", regular_graph.edge_count());
println!(" Edges in 2-section:");
for edge in regular_graph.edges() {
println!(
" {} -- {} (weight: {})",
edge.source, edge.target, edge.weight
);
}
println!("\n8. Incidence matrix:");
let incidence = hypergraph.incidence_matrix();
let num_nodes = incidence.len();
let num_hyperedges = if num_nodes > 0 { incidence[0].len() } else { 0 };
println!(
" Incidence matrix shape: ({}, {})",
num_nodes, num_hyperedges
);
println!(" (rows = nodes, columns = hyperedges)");
let nodes: Vec<_> = hypergraph.nodes().cloned().collect();
let mut sorted_nodes = nodes;
sorted_nodes.sort();
for (i, node) in sorted_nodes.iter().enumerate() {
print!(" {node}: ");
#[allow(clippy::needless_range_loop)]
for j in 0..num_hyperedges {
print!("{} ", incidence[i][j]);
}
println!();
}
println!("\n9. Maximal cliques:");
let cliques = hypergraph.maximal_cliques();
for (i, clique) in cliques.iter().enumerate() {
println!(
" Clique {}: {:?}",
i + 1,
clique.iter().collect::<Vec<_>>()
);
}
println!("\n10. Removing a hyperedge:");
println!(" Removing hyperedge {} (Alice-Diana friendship)", he2);
let removed = hypergraph.remove_hyperedge(he2)?;
println!(
" Removed: {:?} with weight {}",
removed.nodes.iter().collect::<Vec<_>>(),
removed.weight
);
println!(
" Are Alice and Diana still connected? {}",
hypergraph.are_connected(&"Alice", &"Diana")
);
println!(" Remaining hyperedges: {}", hypergraph.hyperedge_count());
println!("\n=== Demo Complete ===");
Ok(())
}