use super::ColorEdge;
use crate::utilities;
use crate::{Centers, ClusteringProblem, ColoredMetric};
pub(super) fn determine_neighborhood<M: ColoredMetric>(
space: &M,
prob: &ClusteringProblem,
gonzalez: &Centers,
) -> Vec<Vec<ColorEdge>> {
let mut edges_of_cluster: Vec<Vec<ColorEdge>> = vec![Vec::with_capacity(prob.k); prob.k];
(0..prob.k).for_each(|i| {
let mut edges_by_color: Vec<Vec<ColorEdge>> = vec![Vec::new(); space.gamma()];
for p in space.point_iter() {
let color = space.color(p);
edges_by_color[space.color(p)].push(ColorEdge {
d: space.dist(gonzalez.get(i, space), p),
center: i,
point: p.idx(),
color,
});
}
let restricted_colors = if space.gamma() < prob.rep_intervals.len() {
space.gamma()
} else {
prob.rep_intervals.len()
}; let mut remaining_edges: Vec<ColorEdge> = Vec::new();
let mut num_edges_to_fill = prob.k;
(0..restricted_colors).for_each(|c| {
utilities::truncate_to_smallest(&mut edges_by_color[c], prob.rep_intervals[c].1);
let a = prob.rep_intervals[c].0;
utilities::split_in_two_at(&mut edges_by_color[c], a);
let bigger = edges_by_color[c].split_off(a);
remaining_edges.extend(bigger);
num_edges_to_fill -= a;
});
(restricted_colors..space.gamma()).for_each(|c| {
remaining_edges.append(&mut edges_by_color[c]);
});
utilities::truncate_to_smallest(&mut remaining_edges, num_edges_to_fill);
(0..restricted_colors).for_each(|c| {
edges_of_cluster[i].append(&mut edges_by_color[c]);
});
edges_of_cluster[i].extend(remaining_edges);
edges_of_cluster[i].sort_by(|a, b| a.partial_cmp(b).unwrap());
});
edges_of_cluster
}