~ruther/ctu-fee-eoa

41658e700956f2bc41f9835ffd23128c073eb786 — Rutherther 25 days ago c95e314
fix(eoa_lib): extract random distribution parameter out of perturbation
2 files changed, 34 insertions(+), 15 deletions(-)

M codes/eoa_lib/src/evolutionary_strategy.rs
M codes/eoa_lib/src/perturbation/mod.rs
M codes/eoa_lib/src/evolutionary_strategy.rs => codes/eoa_lib/src/evolutionary_strategy.rs +7 -7
@@ 3,7 3,7 @@ use std::{convert::Infallible, error::Error};
use nalgebra::SVector;
use rand_distr::{Normal, NormalError};

use crate::{local_search::LocalSearchStats, perturbation::{apply_to_perturbations, PerturbationOperator, RandomDistributionPerturbation}};
use crate::{local_search::LocalSearchStats, perturbation::{apply_to_perturbations, PerturbationOperator, RandomDistributionParameter, RandomDistributionPerturbation}};

pub trait EvolutionaryStrategy<TOut, TPerturbation: PerturbationOperator> {
    type Err: Error + 'static;


@@ 15,9 15,9 @@ pub trait EvolutionaryStrategy<TOut, TPerturbation: PerturbationOperator> {
    ) -> Result<(), Self::Err>;
}

fn normal_one_to_five<const LEN: usize>(perturbation: &mut RandomDistributionPerturbation<LEN, Normal<f64>>, better: bool) -> Result<(), NormalError> {
fn normal_one_to_five<const LEN: usize>(params: &mut RandomDistributionParameter<Normal<f64>>, better: bool) -> Result<(), NormalError> {
    let exp: f64 = if better { 1.0 } else { 0.0 } - 0.2;
    let sigma = perturbation.std_dev();
    let sigma = params.parameter;

    let new_sigma = sigma * exp.exp().powf(1.0 / LEN as f64);



@@ 28,7 28,7 @@ fn normal_one_to_five<const LEN: usize>(perturbation: &mut RandomDistributionPer
        new_sigma
    };

    perturbation.set_std_dev(new_sigma)?;
    params.parameter = new_sigma;
    Ok(())
}



@@ 45,11 45,11 @@ impl<const LEN: usize,
    ) -> Result<(), Self::Err> {
        let mut found = false;
        let mut result = Ok(());
        apply_to_perturbations::<_, RandomDistributionPerturbation<LEN, Normal<f64>>>(
        apply_to_perturbations::<_, RandomDistributionParameter<Normal<f64>>>(
            perturbation,
            &mut |perturbation| {
            &mut |params| {
                found = true;
                result = normal_one_to_five(perturbation, better);
                result = normal_one_to_five::<LEN>(params, better);
            }
        );


M codes/eoa_lib/src/perturbation/mod.rs => codes/eoa_lib/src/perturbation/mod.rs +27 -8
@@ 176,25 176,33 @@ where
    }
}

pub struct RandomDistributionParameter<TDistribution> {
    pub parameter: f64,
    _phantom: PhantomData<TDistribution>
}

pub struct RandomDistributionPerturbation<const LEN: usize, TDistribution: Distribution<f64>> {
    distribution: TDistribution,
    parameter: f64
    params: RandomDistributionParameter<TDistribution>
}

impl<const LEN: usize> RandomDistributionPerturbation<LEN, Normal<f64>> {
    pub fn normal(std_dev: f64) -> Result<Self, NormalError> {
        Ok(Self {
            distribution: Normal::new(0.0, std_dev)?,
            parameter: std_dev
            params: RandomDistributionParameter {
                parameter: std_dev,
                _phantom: PhantomData
            }
        })
    }

    pub fn std_dev(&self) -> f64 {
        self.parameter
        self.params.parameter
    }

    pub fn set_std_dev(&mut self, std_dev: f64) -> Result<f64, NormalError> {
        self.parameter = std_dev;
        self.params.parameter = std_dev;
        self.distribution = Normal::new(0.0, std_dev)?;
        Ok(std_dev)
    }


@@ 204,27 212,38 @@ impl<const LEN: usize> RandomDistributionPerturbation<LEN, Uniform<f64>> {
    pub fn uniform(range: f64) -> Result<Self, uniform::Error> {
        Ok(Self {
            distribution: Uniform::new(-range/2.0, range/2.0)?,
            parameter: range,
            params: RandomDistributionParameter {
                parameter: range,
                _phantom: PhantomData
            }
        })
    }

    pub fn range(&self) -> f64 {
        self.parameter
        self.params.parameter
    }

    pub fn set_range(&mut self, range: f64) -> Result<f64, uniform::Error> {
        self.parameter = range;
        self.params.parameter = range;
        self.distribution = Uniform::new(-range/2.0, range/2.0)?;
        Ok(range)
    }
}

impl<TDistribution: Distribution<f64>, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
impl<TDistribution: Distribution<f64> + 'static, const LEN: usize> PerturbationOperator for RandomDistributionPerturbation<LEN, TDistribution> {
    type Chromosome = SVector<f64, LEN>;

    fn perturb(&self, chromosome: &mut Self::Chromosome, rng: &mut dyn RngCore) {
        *chromosome += Self::Chromosome::zeros().map(|_| self.distribution.sample(rng));
    }

    fn try_get_params(&self) -> Option<&dyn Any> {
        Some(&self.params)
    }

    fn try_get_params_mut(&mut self) -> Option<&mut dyn Any> {
        Some(&mut self.params)
    }
}

pub struct PatternPerturbation<const LEN: usize> {