~ruther/ctu-fee-eoa

f6ad831f9ffa6d5ab503dd1e6c28f28487110783 — Rutherther 25 days ago ee1d949
feat: add multiple weights to constrained functions
1 files changed, 24 insertions(+), 15 deletions(-)

M codes/eoa_lib/src/constraints.rs
M codes/eoa_lib/src/constraints.rs => codes/eoa_lib/src/constraints.rs +24 -15
@@ 10,7 10,7 @@ pub trait ConstraintFunction {
    type Err: Error + 'static;

    fn evaluate(&self, chromosome: &Self::Chromosome) -> Result<Self::Out, Self::Err>;
    fn is_valid(&self, chromosome: &Self::Chromosome) -> Result<bool, Self::Err>;
    fn is_feasible(&self, chromosome: &Self::Chromosome) -> Result<bool, Self::Err>;
}

pub struct LowerThanConstraintFunction<TChromosome, TOut> {


@@ 34,7 34,7 @@ impl<TChromosome, TOut: Default + PartialOrd> ConstraintFunction for LowerThanCo
        Ok((self.fun)(chromosome))
    }

    fn is_valid(&self, chromosome: &Self::Chromosome) -> Result<bool, Self::Err> {
    fn is_feasible(&self, chromosome: &Self::Chromosome) -> Result<bool, Self::Err> {
        Ok(self.evaluate(chromosome)? <= Default::default())
    }
}


@@ 46,8 46,8 @@ pub struct ConstrainedFitnessFunction<'a,
    TFitness: FitnessFunction<In = TIn, Out = TOut>,
    TConstraint: ConstraintFunction<Chromosome = TIn, Out = TOut>> {
    fitness: &'a TFitness,
    constraints: Vec<&'a TConstraint>,
    constraints_weight: TOut
    constraints: [&'a TConstraint; CONSTRAINTS],
    constraint_weights: Vec<TOut>
}

#[derive(Error, Debug)]


@@ 76,8 76,8 @@ impl <'a,
                return Err(ConstrainedFitnessErr::FitnessErr(err))
        };

        for &constraint in &self.constraints {
            fit += self.constraints_weight * match constraint.evaluate(inp) {
        for (constraint, weight) in self.constraints.iter().zip(self.constraint_weights.iter()) {
            fit += weight.clone() * match constraint.evaluate(inp) {
                Ok(constraint) => constraint,
                Err(err) =>
                    return Err(ConstrainedFitnessErr::ConstraintErr(err))


@@ 136,17 136,19 @@ pub fn evolve_constraint_penalty_weight_k
            let best_candidate = population.best_candidate(better_than);
            let feasible = fitness.constraints
                .iter()
                .any(|c| c.is_valid(&best_candidate.chromosome)
                .any(|c| c.is_feasible(&best_candidate.chromosome)
                     .expect("Can verify candidates"));

            // Change weight this iteration?
            if iteration % n == 0 {
                let all_feasible = k_iters_feasible.iter().all(|&f| f);

                fitness.constraints_weight *= if all_feasible {
                    1.0 / beta_1
                } else {
                    beta_2
                for constraint_weight in fitness.constraint_weights.iter_mut() {
                    *constraint_weight *= if all_feasible {
                        1.0 / beta_1
                    } else {
                        beta_2
                    };
                }
            }



@@ 199,21 201,28 @@ pub fn evolve_constraint_penalty_weight_tau_target
                return;
            }

            let best_candidate = population.best_candidate(better_than);
            let count_feasible = population.population
                .iter()
                .filter(|individual| {
                    fitness.constraints
                        .iter()
                        .all(|f| f
                             .is_valid(&individual.chromosome)
                             .is_feasible(&individual.chromosome)
                             .expect("Can verify candidates"))
                })
                .count();
            let tau = count_feasible as f64 / population.population.len() as f64;

            if tau > tau_target {
                fitness.constraints_weight *= 1.0 / c;
            for constraint_weight in fitness.constraint_weights.iter_mut() {
                if tau > tau_target {
                    *constraint_weight *= 1.0 / c;
                } else {
                    *constraint_weight *= c;
                }
            }
        }
}

            } else {
                fitness.constraints_weight *= c;
            }