use crate::configuration::ProblemSolving;
use crate::traits::ChromosomeT;
use log::info;
use rand::seq::SliceRandom;
pub fn mass_extinction<U: ChromosomeT>(
chromosomes: &mut Vec<U>,
population_size: usize,
problem_solving: ProblemSolving,
survival_rate: f64,
elite_count: usize,
) {
if chromosomes.is_empty() {
return;
}
let elite_count = elite_count.min(chromosomes.len());
let target_survivors =
((population_size as f64 * survival_rate).ceil() as usize).max(elite_count);
sort_by_fitness(chromosomes, problem_solving);
let elite: Vec<U> = chromosomes.iter().take(elite_count).cloned().collect();
let mut rest: Vec<U> = chromosomes.drain(elite_count..).collect();
chromosomes.clear();
let rest_survivors = target_survivors.saturating_sub(elite_count).min(rest.len());
let mut rng = crate::rng::make_rng();
rest.shuffle(&mut rng);
rest.truncate(rest_survivors);
chromosomes.extend(elite);
chromosomes.extend(rest);
info!(
target = "extension_events",
method = "mass_extinction";
"MassExtinction applied: population reduced to {}",
chromosomes.len()
);
}
fn sort_by_fitness<U: ChromosomeT>(chromosomes: &mut [U], problem_solving: ProblemSolving) {
match problem_solving {
ProblemSolving::Maximization => {
chromosomes.sort_by(|a, b| {
b.fitness()
.partial_cmp(&a.fitness())
.unwrap_or(std::cmp::Ordering::Equal)
});
}
ProblemSolving::Minimization | ProblemSolving::FixedFitness => {
chromosomes.sort_by(|a, b| {
a.fitness()
.partial_cmp(&b.fitness())
.unwrap_or(std::cmp::Ordering::Equal)
});
}
}
}