use crate::spec::laplacian_matrix;
use petgraph::visit::{GraphProp, IntoEdges, IntoNodeIdentifiers, NodeCount, NodeIndexable};
pub fn count_spanning_trees<G>(graph: G, root: G::NodeId) -> usize
where
G: IntoEdges + IntoNodeIdentifiers + NodeCount + NodeIndexable + GraphProp,
{
let mut mtrx = laplacian_matrix(graph, |_| 1.0f32);
mtrx = mtrx.remove_row(graph.to_index(root));
mtrx = mtrx.remove_column(graph.to_index(root));
mtrx.determinant() as usize
}
#[cfg(test)]
mod test {
use super::*;
use petgraph::graph::{Graph, UnGraph};
#[test]
fn test_count_spanning_trees() {
let mut graph = UnGraph::<u32, f32>::new_undirected();
let n0 = graph.add_node(0);
assert_eq!(count_spanning_trees(&graph, n0), 1);
let n1 = graph.add_node(1);
assert_eq!(count_spanning_trees(&graph, n0), 0);
assert_eq!(count_spanning_trees(&graph, n0), 0);
let n2 = graph.add_node(2);
let n3 = graph.add_node(3);
graph.add_edge(n0, n1, 10.0);
graph.add_edge(n1, n2, 20.0);
graph.add_edge(n0, n3, 30.0);
graph.add_edge(n0, n2, 40.0);
graph.add_edge(n3, n2, 50.0);
assert_eq!(count_spanning_trees(&graph, n0), 8);
assert_eq!(count_spanning_trees(&graph, n1), 8);
assert_eq!(count_spanning_trees(&graph, n2), 8);
assert_eq!(count_spanning_trees(&graph, n3), 8);
graph.add_edge(n1, n0, 10.0);
assert_eq!(count_spanning_trees(&graph, n0), 13);
assert_eq!(count_spanning_trees(&graph, n1), 13);
assert_eq!(count_spanning_trees(&graph, n2), 13);
assert_eq!(count_spanning_trees(&graph, n3), 13);
let mut digraph = Graph::<u32, f32>::new();
let n0 = digraph.add_node(0);
assert_eq!(count_spanning_trees(&digraph, n0), 1);
let n1 = digraph.add_node(1);
assert_eq!(count_spanning_trees(&digraph, n0), 0);
assert_eq!(count_spanning_trees(&digraph, n0), 0);
let n2 = digraph.add_node(2);
let n3 = digraph.add_node(3);
digraph.add_edge(n0, n1, 10.0);
digraph.add_edge(n2, n1, 20.0);
digraph.add_edge(n3, n0, 30.0);
digraph.add_edge(n2, n0, 40.0);
digraph.add_edge(n2, n3, 50.0);
assert_eq!(count_spanning_trees(&digraph, n0), 0);
assert_eq!(count_spanning_trees(&digraph, n1), 3);
assert_eq!(count_spanning_trees(&digraph, n2), 0);
assert_eq!(count_spanning_trees(&digraph, n3), 0);
digraph.add_edge(n1, n0, 10.0);
assert_eq!(count_spanning_trees(&digraph, n0), 3);
assert_eq!(count_spanning_trees(&digraph, n1), 3);
assert_eq!(count_spanning_trees(&digraph, n2), 0);
assert_eq!(count_spanning_trees(&digraph, n3), 0);
}
}