use super::*;
pub struct MaxIterations {
max_iter: usize,
}
impl MaxIterations {
pub fn new(max_iter: usize) -> Self {
MaxIterations { max_iter }
}
}
impl<T: Clone> StopChecker<T> for MaxIterations {
fn can_stop(&mut self, population: &Population<T>) -> bool {
population.get_iteration() >= self.max_iter
}
}
pub struct GoalNotChange {
max_iter: usize,
delta: f64,
old_goal: f64,
change_iter: usize,
}
impl GoalNotChange {
pub fn new(max_iter: usize, delta: f64) -> Self {
GoalNotChange {
max_iter,
delta,
old_goal: f64::MAX,
change_iter: 0,
}
}
}
impl<T: Clone> StopChecker<T> for GoalNotChange {
fn can_stop(&mut self, population: &Population<T>) -> bool {
match population.get_best() {
None => false,
Some(individual) => {
let best_goal = individual.get_goal();
let delta = (best_goal - self.old_goal).abs();
if delta > self.delta {
self.old_goal = best_goal;
self.change_iter = population.get_iteration();
}
(population.get_iteration() - self.change_iter) > self.max_iter
}
}
}
}
pub struct Threshold {
threshold: f64,
}
impl Threshold {
pub fn new(threshold: f64) -> Self {
Self { threshold }
}
}
impl<T: Clone> StopChecker<T> for Threshold {
fn can_stop(&mut self, population: &Population<T>) -> bool {
match population.get_best() {
None => false,
Some(individual) => individual.get_goal() <= self.threshold,
}
}
}
pub struct CompositeAny<T: Clone> {
stop_checkers: Vec<Box<dyn StopChecker<T>>>,
}
impl<T: Clone> CompositeAny<T> {
pub fn new(stop_checkers: Vec<Box<dyn StopChecker<T>>>) -> Self {
assert!(stop_checkers.len() != 0);
Self { stop_checkers }
}
}
impl<T: Clone> StopChecker<T> for CompositeAny<T> {
fn can_stop(&mut self, population: &Population<T>) -> bool {
for checker in &mut self.stop_checkers {
if checker.can_stop(population) {
return true
}
}
false
}
}
pub struct CompositeAll<T: Clone> {
stop_checkers: Vec<Box<dyn StopChecker<T>>>,
}
impl<T: Clone> CompositeAll<T> {
pub fn new(stop_checkers: Vec<Box<dyn StopChecker<T>>>) -> Self {
assert!(stop_checkers.len() != 0);
Self { stop_checkers }
}
}
impl<T: Clone> StopChecker<T> for CompositeAll<T> {
fn can_stop(&mut self, population: &Population<T>) -> bool {
for checker in &mut self.stop_checkers {
if !checker.can_stop(population) {
return false
}
}
true
}
}