use crate::clustering::Centers;
use crate::types::{CenterIdx, Distance, PointCount};
use std::collections::VecDeque;
use std::fmt;
#[derive(Debug)]
pub(crate) struct OpeningList {
pub eta: Vec<PointCount>,
pub forrest_radius: Distance,
}
impl fmt::Display for OpeningList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(")?;
let mut iter = self.eta.iter();
if let Some(c) = iter.next() {
write!(f, "{}", c)?;
}
for c in iter {
write!(f, ", {}", c)?;
}
write!(f, ") for forrest_radius = {}", self.forrest_radius)?;
Ok(())
}
}
#[derive(Debug)]
pub(crate) struct NewCenters {
pub as_points: Centers,
pub forrest_radius: Distance,
pub assignment_radius: Distance,
pub new_centers_of_cluster: Vec<Vec<CenterIdx>>,
}
#[derive(Debug)]
pub(crate) struct RootedSpanningTree {
edges: Vec<Option<UpEdge>>, edges_to_children: Vec<Vec<UpEdge>>, }
impl RootedSpanningTree {
pub fn new(
edges: Vec<Option<UpEdge>>,
edges_to_children: Vec<Vec<UpEdge>>,
) -> RootedSpanningTree {
RootedSpanningTree {
edges,
edges_to_children,
}
}
pub fn get_edge(&self, node: CenterIdx, threshold: Distance) -> Option<&UpEdge> {
self.edges[node].as_ref().filter(|edge| edge.d <= threshold)
}
pub fn get_edges(&self, threshold: Distance) -> Vec<&UpEdge> {
self.edges
.iter()
.filter_map(|e| e.as_ref())
.filter(|e| e.d <= threshold)
.collect()
}
pub fn get_edges_to_children(&self, node: CenterIdx, threshold: Distance) -> Vec<&UpEdge> {
self.edges_to_children[node]
.iter()
.filter(|e| e.d <= threshold)
.collect()
}
pub fn get_sorted_dist(&self) -> Vec<Distance> {
let mut distances: Vec<Distance> = self
.edges
.iter()
.filter_map(|o| o.as_ref())
.map(|e| e.d)
.collect();
distances.sort_by(|a, b| a.partial_cmp(b).unwrap());
distances
}
pub fn build_bfs_stack(&self, threshold: Distance) -> Vec<CenterIdx> {
let i = self.edges.len() - 1;
let mut stack: Vec<CenterIdx> = Vec::with_capacity(i + 1); let mut is_root = vec![true; i + 1];
for e in self.get_edges(threshold).iter() {
is_root[e.down] = false;
}
let mut queue: VecDeque<CenterIdx> = VecDeque::with_capacity(i + 1); let mut pushed = vec![false; i + 1]; for j in (0..i + 1).filter(|l| is_root[*l]) {
queue.push_back(j);
pushed[j] = true;
}
while !queue.is_empty() {
let node = queue.pop_front().unwrap();
stack.push(node);
for &edge in self.get_edges_to_children(node, threshold).iter() {
let next = edge.down;
if !pushed[next] {
pushed[next] = true;
queue.push_back(next);
}
}
}
stack
}
}
impl fmt::Display for RootedSpanningTree {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "(")?;
let mut iter = self.edges.iter().flatten();
if let Some(first_edge) = iter.next() {
write!(f, "{} -> {}", first_edge.down, first_edge.up)?;
for edge in iter {
write!(f, ", {} -> {}", edge.down, edge.up)?;
}
};
write!(f, ")")?;
Ok(())
}
}
#[derive(Debug, Clone)]
pub(crate) struct UpEdge {
pub d: Distance,
pub up: CenterIdx, pub down: CenterIdx, }