use std::fmt::Display;
use crate::solution::Solution;
use crate::problem::traits::Problem;
pub trait SolutionSet<T, Q = f64>
where
T: Clone,
Q: Clone + 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<P>(&self, problem: &P) -> Option<&Solution<T, Q>>
where
Self: Sized,
P: Problem<T, Q>,
{
let mut best: Option<&Solution<T, Q>> = None;
for solution in self.iter() {
let should_replace = match best {
Some(current_best) => problem.dominates(solution, current_best),
None => true,
};
if should_replace {
best = Some(solution);
}
}
best
}
fn best_solution_value<P>(&self, problem: &P) -> Option<f64>
where
Self: Sized,
P: Problem<T, Q>,
T: Display,
Q: Copy + Into<f64>,
{
self.best_solution(problem)
.and_then(|solution| solution.quality().copied().map(Into::into))
}
fn best_solution_value_or<P>(&self, problem: &P, default: f64) -> f64
where
Self: Sized,
P: Problem<T, Q>,
T: Display,
Q: Copy + Into<f64>,
{
self.best_solution_value(problem).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)
}
}