use crate::configuration::ProblemSolving;
use crate::traits::{GeneT, LinearChromosome};
use std::collections::HashMap;
use std::hash::{DefaultHasher, Hash, Hasher};
pub fn mass_deduplication<U: LinearChromosome>(
chromosomes: &mut Vec<U>,
problem_solving: ProblemSolving,
) {
if chromosomes.is_empty() {
return;
}
let original_len = chromosomes.len();
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)
});
}
}
let mut seen: HashMap<u64, Vec<i32>> = HashMap::new();
chromosomes.retain(|c| {
let mut hasher = DefaultHasher::new();
for g in c.dna() {
g.id().hash(&mut hasher);
}
let h = hasher.finish();
match seen.entry(h) {
std::collections::hash_map::Entry::Vacant(e) => {
let ids: Vec<i32> = c.dna().iter().map(|g| g.id()).collect();
e.insert(ids);
true }
std::collections::hash_map::Entry::Occupied(e) => {
let ids: Vec<i32> = c.dna().iter().map(|g| g.id()).collect();
if ids != *e.get() {
true } else {
false }
}
}
});
let removed = original_len - chromosomes.len();
crate::log_info!(
target = "extension_events",
method = "mass_deduplication";
"MassDeduplication applied: removed {} duplicates, {} unique remain",
removed,
chromosomes.len()
);
}