use crate::error::GaError;
use crate::traits::ChromosomeT;
use log::debug;
use rand::Rng;
use std::borrow::Cow;
pub fn insertion_mutation<U: ChromosomeT>(individual: &mut U) -> Result<(), GaError> {
let len = individual.dna().len();
if len < 2 {
debug!(target="mutation_events", method="insertion"; "DNA length < 2, skipping insertion mutation");
return Ok(());
}
let mut rng = crate::rng::make_rng();
let i = rng.random_range(0..len);
let mut j = rng.random_range(0..len);
while j == i {
j = rng.random_range(0..len);
}
debug!(target="mutation_events", method="insertion"; "Starting insertion mutation: remove gene at {} and insert near {}", j, i);
let mut dna = individual.dna().to_vec();
let gene = dna.remove(j);
let insert_pos = if j < i {
i
} else {
i + 1
};
let insert_pos = insert_pos.min(dna.len());
dna.insert(insert_pos, gene);
individual.set_dna(Cow::Owned(dna));
debug!(target="mutation_events", method="insertion"; "Insertion mutation finished");
Ok(())
}