use crate::configuration::{LimitConfiguration, ProblemSolving};
use crate::error::GaError;
use crate::operations::Survivor;
use crate::traits::LinearChromosome;
fn adjusted_fitness(
raw_fitness: f64,
dna_length: usize,
length_penalty: f64,
problem_solving: ProblemSolving,
) -> f64 {
let adjustment = length_penalty * dna_length as f64;
match problem_solving {
ProblemSolving::Maximization => raw_fitness - adjustment,
ProblemSolving::Minimization | ProblemSolving::FixedFitness => raw_fitness + adjustment,
}
}
pub fn apply_parsimony_pressure<U: LinearChromosome>(
survivor: Survivor,
chromosomes: &mut Vec<U>,
population_size: usize,
limit_configuration: LimitConfiguration,
length_penalty: f64,
) -> Result<(), GaError> {
crate::log_debug!(
target = "survivor_events",
method = "parsimony";
"Applying parsimony pressure (penalty={}, mode={:?}, pop={})",
length_penalty, limit_configuration.problem_solving, chromosomes.len()
);
let problem_solving = limit_configuration.problem_solving;
for c in chromosomes.iter_mut() {
let raw = c.fitness();
let len = c.dna().len();
let adj = adjusted_fitness(raw, len, length_penalty, problem_solving);
c.set_fitness(adj);
}
let result = super::factory(survivor, chromosomes, population_size, limit_configuration);
for c in chromosomes.iter_mut() {
let adj = c.fitness();
let len = c.dna().len();
let raw = match problem_solving {
ProblemSolving::Maximization => adj + length_penalty * len as f64,
ProblemSolving::Minimization | ProblemSolving::FixedFitness => {
adj - length_penalty * len as f64
}
};
c.set_fitness(raw);
}
result
}