From f6ad831f9ffa6d5ab503dd1e6c28f28487110783 Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 16 Nov 2025 19:51:14 +0100 Subject: [PATCH] feat: add multiple weights to constrained functions --- codes/eoa_lib/src/constraints.rs | 39 ++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/codes/eoa_lib/src/constraints.rs b/codes/eoa_lib/src/constraints.rs index 9101cd7d01dbb693d8c208a6c0a390f961a77380..18706f5d31ae9d198513280d3c58819ba7fe2e7a 100644 --- a/codes/eoa_lib/src/constraints.rs +++ b/codes/eoa_lib/src/constraints.rs @@ -10,7 +10,7 @@ pub trait ConstraintFunction { type Err: Error + 'static; fn evaluate(&self, chromosome: &Self::Chromosome) -> Result; - fn is_valid(&self, chromosome: &Self::Chromosome) -> Result; + fn is_feasible(&self, chromosome: &Self::Chromosome) -> Result; } pub struct LowerThanConstraintFunction { @@ -34,7 +34,7 @@ impl ConstraintFunction for LowerThanCo Ok((self.fun)(chromosome)) } - fn is_valid(&self, chromosome: &Self::Chromosome) -> Result { + fn is_feasible(&self, chromosome: &Self::Chromosome) -> Result { Ok(self.evaluate(chromosome)? <= Default::default()) } } @@ -46,8 +46,8 @@ pub struct ConstrainedFitnessFunction<'a, TFitness: FitnessFunction, TConstraint: ConstraintFunction> { fitness: &'a TFitness, - constraints: Vec<&'a TConstraint>, - constraints_weight: TOut + constraints: [&'a TConstraint; CONSTRAINTS], + constraint_weights: Vec } #[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; }