M env/src/evolutionary_strategy.rs => env/src/evolutionary_strategy.rs +7 -6
@@ 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<TOut, TPerturbation: PerturbationOperator> {
type Err;
@@ 11,7 11,7 @@ pub trait EvolutionaryStrategy<TOut, TPerturbation: PerturbationOperator> {
fn step(&mut self,
perturbation: &mut TPerturbation,
better: bool,
- stats: &Vec<LocalSearchCandidate<TPerturbation::Chromosome, TOut>>
+ stats: &LocalSearchStats<TPerturbation::Chromosome, TOut>
) -> Result<(), Self::Err>;
}
@@ 32,23 32,24 @@ impl<const LEN: usize, TOut> EvolutionaryStrategy<TOut, RandomDistributionPertur
fn step(&mut self,
perturbation: &mut RandomDistributionPerturbation<LEN, Normal<f64>>,
better: bool,
- _: &Vec<LocalSearchCandidate<SVector::<f64, LEN>, TOut>>
+ _: &LocalSearchStats<SVector::<f64, LEN>, 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<const LEN: usize, TOut> EvolutionaryStrategy<TOut, BoundedPerturbation<LEN, RandomDistributionPerturbation<LEN, Normal<f64>>>> for OneToFiveStrategy {
type Err = NormalError;
fn step(&mut self,
perturbation: &mut BoundedPerturbation<LEN, RandomDistributionPerturbation<LEN, Normal<f64>>>,
better: bool,
- _: &Vec<LocalSearchCandidate<<BoundedPerturbation<LEN, RandomDistributionPerturbation<LEN, Normal<f64>>> as PerturbationOperator>::Chromosome, TOut>>
+ _: &LocalSearchStats<<BoundedPerturbation<LEN, RandomDistributionPerturbation<LEN, Normal<f64>>> as PerturbationOperator>::Chromosome, TOut>
) -> Result<(), Self::Err> {
normal_one_to_five(perturbation.inner_mut(), better)
}
-
}
pub struct IdentityStrategy;
@@ 58,7 59,7 @@ impl<TOut, TPerturbation: PerturbationOperator> EvolutionaryStrategy<TOut, TPert
fn step(&mut self,
_: &mut TPerturbation,
_: bool,
- _: &Vec<LocalSearchCandidate<TPerturbation::Chromosome, TOut>>
+ _: &LocalSearchStats<TPerturbation::Chromosome, TOut>
) -> Result<(), Self::Err> {
Ok(())
}
M env/src/local_search/mod.rs => env/src/local_search/mod.rs +24 -3
@@ 15,6 15,27 @@ pub struct LocalSearchCandidate<TInput, TResult>
}
#[derive(Debug, Clone, PartialEq)]
+pub struct LocalSearchStats<TInput, TResult> {
+ stats: Vec<LocalSearchCandidate<TInput, TResult>>
+}
+
+impl<TInput, TResult> LocalSearchStats<TInput, TResult> {
+ pub fn new() -> Self {
+ Self {
+ stats: vec![]
+ }
+ }
+
+ pub fn stats(&self) -> &Vec<LocalSearchCandidate<TInput, TResult>> {
+ &self.stats
+ }
+
+ pub fn append(&mut self, candidate: LocalSearchCandidate<TInput, TResult>) {
+ self.stats.push(candidate)
+ }
+}
+
+#[derive(Debug, Clone, PartialEq)]
pub struct LocalSearchResult<TInput, TResult>
where TResult: Clone
{
@@ 24,7 45,7 @@ pub struct LocalSearchResult<TInput, TResult>
pub cycles: usize,
// statistics
- pub best_candidates: Vec<LocalSearchCandidate<TInput, TResult>>
+ pub best_candidates: LocalSearchStats<TInput, TResult>
}
fn local_search_first_improving<
@@ 78,7 99,7 @@ where
cycle: 0
};
- let mut stats: Vec<LocalSearchCandidate<TInput, TResult>> = 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 {
M env/src/terminating/mod.rs => env/src/terminating/mod.rs +5 -5
@@ 1,11 1,11 @@
-use crate::{binary_string::BinaryString, local_search::LocalSearchCandidate};
+use crate::{binary_string::BinaryString, local_search::{LocalSearchCandidate, LocalSearchStats}};
pub trait TerminatingCondition<TInput, TResult>
{
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<TInput, TResult>,
- stats: &Vec<LocalSearchCandidate<TInput, TResult>>,
+ stats: &LocalSearchStats<TInput, TResult>,
cycle: usize
) -> bool;
}
@@ 46,7 46,7 @@ where
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<TInput, TResult>,
- _: &Vec<LocalSearchCandidate<TInput, TResult>>,
+ _: &LocalSearchStats<TInput, TResult>,
_: usize
) -> bool {
let matched = candidate.pos == self.target;
@@ 87,7 87,7 @@ impl<'a, TInput, TResult> TerminatingCondition<TInput, TResult> for AndTerminati
fn should_terminate(
self: &mut Self,
candidate: &LocalSearchCandidate<TInput, TResult>,
- stats: &Vec<LocalSearchCandidate<TInput, TResult>>,
+ stats: &LocalSearchStats<TInput, TResult>,
cycle: usize
) -> bool {
return self.terminating_conditions.iter_mut()
@@ 101,7 101,7 @@ impl<TInput, TResult> TerminatingCondition<TInput, TResult> for NoBetterForCycle
fn should_terminate (
self: &mut Self,
candidate: &LocalSearchCandidate<TInput, TResult>,
- _: &Vec<LocalSearchCandidate<TInput, TResult>>,
+ _: &LocalSearchStats<TInput, TResult>,
cycle: usize
) -> bool {
(cycle - candidate.cycle) > self.cycles