use std::fmt::{Display, Formatter};
#[derive(Clone, Copy, serde::Serialize, serde::Deserialize, Debug, PartialEq, Eq)]
pub enum ClusteringAlgorithmName {
KMeans,
Agglomerative,
DBSCAN,
}
#[derive(Clone, serde::Serialize, serde::Deserialize)]
pub struct ClusteringSettings {
pub(crate) k: usize,
pub(crate) max_iter: usize,
pub(crate) eps: f64,
pub(crate) min_samples: usize,
pub(crate) algorithms: Vec<ClusteringAlgorithmName>,
pub(crate) verbose: bool,
}
impl Default for ClusteringSettings {
fn default() -> Self {
Self {
k: 2,
max_iter: 100,
eps: 0.5,
min_samples: 5,
algorithms: vec![
ClusteringAlgorithmName::KMeans,
ClusteringAlgorithmName::Agglomerative,
ClusteringAlgorithmName::DBSCAN,
],
verbose: false,
}
}
}
impl ClusteringSettings {
#[must_use]
pub const fn with_k(mut self, k: usize) -> Self {
self.k = k;
self
}
#[must_use]
pub const fn with_max_iter(mut self, max_iter: usize) -> Self {
self.max_iter = max_iter;
self
}
#[must_use]
pub fn with_eps(mut self, eps: f64) -> Self {
self.eps = eps;
self
}
#[must_use]
pub const fn with_min_samples(mut self, min_samples: usize) -> Self {
self.min_samples = min_samples;
self
}
#[must_use]
pub fn with_algorithm(mut self, algorithm: ClusteringAlgorithmName) -> Self {
self.algorithms = vec![algorithm];
self
}
#[must_use]
pub fn with_algorithms(mut self, algorithms: Vec<ClusteringAlgorithmName>) -> Self {
if algorithms.is_empty() {
return self;
}
self.algorithms = algorithms;
self
}
#[must_use]
pub const fn verbose(mut self, verbose: bool) -> Self {
self.verbose = verbose;
self
}
#[must_use]
pub(crate) fn selected_algorithms(&self) -> Vec<ClusteringAlgorithmName> {
if self.algorithms.is_empty() {
return vec![
ClusteringAlgorithmName::KMeans,
ClusteringAlgorithmName::Agglomerative,
ClusteringAlgorithmName::DBSCAN,
];
}
self.algorithms.clone()
}
}
impl Display for ClusteringAlgorithmName {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::KMeans => write!(f, "KMeans"),
Self::Agglomerative => write!(f, "Agglomerative"),
Self::DBSCAN => write!(f, "DBSCAN"),
}
}
}