From cd58504de4e214a0d9b406d6800a63812d0e8198 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Fri, 17 Oct 2025 15:08:01 +0200 Subject: [PATCH] refactor: abstract LocalSearch stats into LocalSearchStats --- env/src/evolutionary_strategy.rs | 13 +++++++------ env/src/local_search/mod.rs | 27 ++++++++++++++++++++++++--- env/src/terminating/mod.rs | 10 +++++----- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/env/src/evolutionary_strategy.rs b/env/src/evolutionary_strategy.rs index d235f57bde2253d85d0e7cbfb4369d3720d4a31b..0a6f2c5dc7fe866bf3279b01461b52afcc1e816b 100644 --- a/env/src/evolutionary_strategy.rs +++ b/env/src/evolutionary_strategy.rs @@ -3,7 +3,7 @@ use std::convert::Infallible; use nalgebra::SVector; use rand_distr::{Normal, NormalError}; -use crate::{local_search::LocalSearchCandidate, perturbation::{BoundedPerturbation, PerturbationOperator, RandomDistributionPerturbation}}; +use crate::{local_search::{LocalSearchCandidate, LocalSearchStats}, perturbation::{BoundedPerturbation, PerturbationOperator, RandomDistributionPerturbation}}; pub trait EvolutionaryStrategy { type Err; @@ -11,7 +11,7 @@ pub trait EvolutionaryStrategy { fn step(&mut self, perturbation: &mut TPerturbation, better: bool, - stats: &Vec> + stats: &LocalSearchStats ) -> Result<(), Self::Err>; } @@ -32,23 +32,24 @@ impl EvolutionaryStrategy>, better: bool, - _: &Vec, TOut>> + _: &LocalSearchStats, TOut> ) -> Result<(), Self::Err> { normal_one_to_five(perturbation, better) } } +// TODO: I don't really like this to be honest. This would basically have to take care of any perturbation wrapper +// that there is. But that just seems wrong. impl EvolutionaryStrategy>>> for OneToFiveStrategy { type Err = NormalError; fn step(&mut self, perturbation: &mut BoundedPerturbation>>, better: bool, - _: &Vec>> as PerturbationOperator>::Chromosome, TOut>> + _: &LocalSearchStats<>> as PerturbationOperator>::Chromosome, TOut> ) -> Result<(), Self::Err> { normal_one_to_five(perturbation.inner_mut(), better) } - } pub struct IdentityStrategy; @@ -58,7 +59,7 @@ impl EvolutionaryStrategy> + _: &LocalSearchStats ) -> Result<(), Self::Err> { Ok(()) } diff --git a/env/src/local_search/mod.rs b/env/src/local_search/mod.rs index 952b13d83b8a4b09217cc2a1b73b96faa029d2e6..34d0370d9f953ee740b8bd178efed33b7086f53d 100644 --- a/env/src/local_search/mod.rs +++ b/env/src/local_search/mod.rs @@ -14,6 +14,27 @@ pub struct LocalSearchCandidate pub cycle: usize } +#[derive(Debug, Clone, PartialEq)] +pub struct LocalSearchStats { + stats: Vec> +} + +impl LocalSearchStats { + pub fn new() -> Self { + Self { + stats: vec![] + } + } + + pub fn stats(&self) -> &Vec> { + &self.stats + } + + pub fn append(&mut self, candidate: LocalSearchCandidate) { + self.stats.push(candidate) + } +} + #[derive(Debug, Clone, PartialEq)] pub struct LocalSearchResult where TResult: Clone @@ -24,7 +45,7 @@ pub struct LocalSearchResult pub cycles: usize, // statistics - pub best_candidates: Vec> + pub best_candidates: LocalSearchStats } fn local_search_first_improving< @@ -78,7 +99,7 @@ where cycle: 0 }; - let mut stats: Vec> = vec![]; + let mut stats = LocalSearchStats::new(); let mut cycle: usize = 0; while !terminating_condition.should_terminate(&best_candidate, &stats, cycle) { @@ -93,7 +114,7 @@ where cycle }; - stats.push(best_candidate.clone()); + stats.append(best_candidate.clone()); true } else { diff --git a/env/src/terminating/mod.rs b/env/src/terminating/mod.rs index 55e2a844d0e61fbb930da39300cb85570e3565a1..c63ac89ecee48d52151336f4a0c9fa647511e411 100644 --- a/env/src/terminating/mod.rs +++ b/env/src/terminating/mod.rs @@ -1,11 +1,11 @@ -use crate::{binary_string::BinaryString, local_search::LocalSearchCandidate}; +use crate::{binary_string::BinaryString, local_search::{LocalSearchCandidate, LocalSearchStats}}; pub trait TerminatingCondition { fn should_terminate( self: &mut Self, candidate: &LocalSearchCandidate, - stats: &Vec>, + stats: &LocalSearchStats, cycle: usize ) -> bool; } @@ -46,7 +46,7 @@ where fn should_terminate( self: &mut Self, candidate: &LocalSearchCandidate, - _: &Vec>, + _: &LocalSearchStats, _: usize ) -> bool { let matched = candidate.pos == self.target; @@ -87,7 +87,7 @@ impl<'a, TInput, TResult> TerminatingCondition for AndTerminati fn should_terminate( self: &mut Self, candidate: &LocalSearchCandidate, - stats: &Vec>, + stats: &LocalSearchStats, cycle: usize ) -> bool { return self.terminating_conditions.iter_mut() @@ -101,7 +101,7 @@ impl TerminatingCondition for NoBetterForCycle fn should_terminate ( self: &mut Self, candidate: &LocalSearchCandidate, - _: &Vec>, + _: &LocalSearchStats, cycle: usize ) -> bool { (cycle - candidate.cycle) > self.cycles