use crate::graph::Graph;
#[derive(Debug, Clone)]
pub struct BarycenterEntry {
pub v: String,
pub barycenter: Option<f64>,
pub weight: Option<f64>,
}
pub fn barycenter(graph: &Graph, movable: &[String]) -> Vec<BarycenterEntry> {
movable
.iter()
.map(|v| {
let in_v = graph.in_edges(v).unwrap_or_default();
if in_v.is_empty() {
BarycenterEntry {
v: v.clone(),
barycenter: None,
weight: None,
}
} else {
let (sum, weight) = in_v.iter().fold((0.0f64, 0.0f64), |(sum, weight), e| {
let edge_weight = graph.edge(e).and_then(|l| l.weight).unwrap_or(0.0);
let node_order = graph.node(&e.v).order.unwrap_or(0) as f64;
(sum + edge_weight * node_order, weight + edge_weight)
});
BarycenterEntry {
v: v.clone(),
barycenter: Some(sum / weight),
weight: Some(weight),
}
}
})
.collect()
}