use crate::{binary_string::BinaryString, local_search::LocalSearchCandidate};
pub trait TerminatingCondition<T>
where T: Clone
{
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<T>,
stats: &Vec<LocalSearchCandidate<T>>,
cycle: usize
) -> bool;
}
pub struct EqualTerminatingCondition {
target: BinaryString,
remember_match: bool,
matched: bool,
}
impl EqualTerminatingCondition {
pub fn new(target: BinaryString) -> Self {
Self {
target,
remember_match: false,
matched: false,
}
}
pub fn new_remembered(target: BinaryString) -> Self {
Self {
target,
remember_match: true,
matched: false,
}
}
pub fn reset_match(self: &mut Self) {
self.matched = false;
}
}
impl<T: Clone> TerminatingCondition<T> for EqualTerminatingCondition {
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<T>,
_: &Vec<LocalSearchCandidate<T>>,
_: usize
) -> bool {
let matched = candidate.pos == self.target;
if matched && self.remember_match {
self.matched = true;
}
matched || self.matched
}
}
pub struct NoBetterForCyclesTerminatingCondition {
cycles: usize
}
impl NoBetterForCyclesTerminatingCondition {
pub fn new(cycles: usize) -> Self {
Self {
cycles
}
}
}
pub struct AndTerminatingConditions<'a, T: Clone> {
terminating_conditions: Vec<&'a mut dyn TerminatingCondition<T>>
}
impl<'a, T: Clone> AndTerminatingConditions<'a, T> {
pub fn new(terminating_conditions: Vec<&'a mut dyn TerminatingCondition<T>>) -> Self {
Self {
terminating_conditions
}
}
}
impl<'a, T: Clone> TerminatingCondition<T> for AndTerminatingConditions<'a, T> {
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<T>,
stats: &Vec<LocalSearchCandidate<T>>,
cycle: usize
) -> bool {
return self.terminating_conditions.iter_mut()
.all(
|cond| cond.should_terminate(candidate, stats, cycle)
)
}
}
impl<T: Clone> TerminatingCondition<T> for NoBetterForCyclesTerminatingCondition {
fn should_terminate (
self: &mut Self,
candidate: &LocalSearchCandidate<T>,
_: &Vec<LocalSearchCandidate<T>>,
cycle: usize
) -> bool {
(cycle - candidate.cycle) > self.cycles
}
}