From b172dc70a85dc21ab8b86fb9c264c4f84d6ac75d Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sun, 30 Nov 2025 18:33:40 +0100 Subject: [PATCH] fi: stochastic ranking properly compares constraints only --- codes/eoa_lib/src/constraints.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/codes/eoa_lib/src/constraints.rs b/codes/eoa_lib/src/constraints.rs index 333b5b1171d7bc0601f337e0d1da7ced6162cc29..9931207285832674291611f2070a797c9aca9651 100644 --- a/codes/eoa_lib/src/constraints.rs +++ b/codes/eoa_lib/src/constraints.rs @@ -1,5 +1,6 @@ use std::{collections::VecDeque, convert::Infallible, error::Error}; +use std::fmt::Debug; use rand::{Rng, RngCore}; use thiserror::Error; @@ -229,6 +230,7 @@ pub struct ConstrainedEvaluation { fitness: TOut, constraints: [TOut; CONSTRAINTS], weighted_sum: TOut, + constr_weighted_sum: TOut, is_feasible: bool, } @@ -251,7 +253,7 @@ pub struct ConstrainedEvalFitness<'a, impl <'a, const CONSTRAINTS: usize, - TOut: std::ops::Mul + std::ops::AddAssign + Copy + Default, + TOut: std::ops::Mul + std::ops::AddAssign + std::ops::Add + Copy + Default + PartialOrd + Debug, TIn, TFitness: FitnessFunction, TConstraint: ConstraintFunction> @@ -266,7 +268,7 @@ impl <'a, Err(err) => return Err(ConstrainedFitnessErr::FitnessErr(err)) }; - let mut weighted_sum = fit; + let mut constr_weighted_sum = Default::default(); let mut constraints = [fit; CONSTRAINTS]; let mut is_feasible = true; @@ -278,20 +280,24 @@ impl <'a, }; constraints[i] = constraint_eval; - weighted_sum += match constraint.is_feasible(inp) { - Ok(true) => weight.clone() * constraint_eval, + constr_weighted_sum += match constraint.is_feasible(inp) { Ok(false) => { is_feasible = false; + weight.clone() * constraint_eval + }, + Ok(true) => { Default::default() }, Err(err) => return Err(ConstrainedFitnessErr::ConstraintErr(err)) }; } + assert!(constr_weighted_sum >= Default::default()); Ok(ConstrainedEvaluation { fitness: fit, constraints, - weighted_sum, + constr_weighted_sum, + weighted_sum: fit + constr_weighted_sum, is_feasible }) } @@ -317,7 +323,7 @@ fn stochastic_ranking_sort next_evaluation.weighted_sum { + if current_evaluation.constr_weighted_sum > next_evaluation.constr_weighted_sum { indices.swap(j, j + 1); } } @@ -339,7 +345,7 @@ const MINIMIZING_OPERATOR: MinimizingOperator = MinimizingOperator; impl<'a, const CONSTRAINTS: usize, TChromosome, - TResult: PartialOrd + Default, + TResult: PartialOrd + Default + Clone + Debug, TSelection: Selection<(), usize>, TBetterThan: BetterThanOperator> Selection> for StochasticRankingSelection<'a, TSelection, TBetterThan> { @@ -353,6 +359,8 @@ impl<'a, evaluations.population.as_slice(), self.N, self.p, self.better_than, rng ); + // println!("{:?}", sorted_indices.iter().map(|&x| evaluations.population[x].evaluation.weighted_sum.clone()).collect::>()); + // println!("{:?}", sorted_indices.iter().map(|&x| evaluations.population[x].evaluation.constr_weighted_sum.clone()).collect::>()); let mut rankings = vec![EvaluatedChromosome { chromosome: (), evaluation: 0 @@ -378,7 +386,7 @@ impl<'a, pub fn stochastic_ranking_evolution_algorithm + std::ops::AddAssign + Copy + Default, + TResult: PartialOrd + std::ops::Mul + std::ops::AddAssign + std::ops::Add + Copy + Default + Debug, const DParents: usize, const CONSTRAINTS: usize, TFitness: FitnessFunction, @@ -448,7 +456,7 @@ pub fn stochastic_ranking_evolution_algorithm |iteration, stats, population, fitness, selection, pairing, crossover, perturbation, replacement| { let feasible_fraction = population.population .iter() - .map(|x| x.evaluation.is_feasible) + .filter(|x| x.evaluation.is_feasible) .count() as f64 / population.population.len() as f64; feasible_fractions.push(feasible_fraction);