use std::fmt::Display;
use crate::solution::traits::Dominance;
use crate::solution::Solution;
pub trait SolutionSet<T, Q = f64>
where
T: Clone,
Q: Clone + Dominance + Display,
{
fn iter(&self) -> Box<dyn Iterator<Item = &Solution<T, Q>> + '_>;
fn push_solution(&mut self, solution: Solution<T, Q>);
fn pop_solution(&mut self) -> Option<Solution<T, Q>>;
fn clear_solutions(&mut self);
fn get_solution(&self, index: usize) -> Option<&Solution<T, Q>>;
fn get_solution_mut(&mut self, index: usize) -> Option<&mut Solution<T, Q>>;
fn len(&self) -> usize;
fn add_solution(&mut self, solution: Solution<T, Q>) {
self.push_solution(solution);
}
fn remove_solution(&mut self) -> Option<Solution<T, Q>> {
self.pop_solution()
}
fn clear(&mut self) {
self.clear_solutions();
}
fn is_empty(&self) -> bool {
self.len() == 0
}
fn size(&self) -> usize {
self.len()
}
fn best_solution(&self) -> Option<&Solution<T, Q>> {
let mut best: Option<&Solution<T, Q>> = None;
for solution in self.iter() {
let is_better = match best {
Some(current_best) => solution.dominates(current_best),
None => true,
};
if is_better {
best = Some(solution);
}
}
best
}
fn best_solution_value(&self) -> Option<f64>
where
Q: Copy + Into<f64> + Display,
T: Display,
{
self.best_solution()
.and_then(|s| s.quality().map(|&q| q.into()))
}
fn best_solution_value_or(&self, default: f64) -> f64
where
Q: Copy + Into<f64>,
T: Display,
{
self.best_solution_value().unwrap_or(default)
}
fn get(&self, index: usize) -> Option<&Solution<T, Q>> {
self.get_solution(index)
}
fn get_mut(&mut self, index: usize) -> Option<&mut Solution<T, Q>> {
self.get_solution_mut(index)
}
}