mod clone;
mod multi_gene;
mod multi_point;
mod single_gene;
mod single_point;
mod uniform;
mod wrapper;
pub use self::clone::Clone as CrossoverClone;
pub use self::multi_gene::MultiGene as CrossoverMultiGene;
pub use self::multi_point::MultiPoint as CrossoverMultiPoint;
pub use self::single_gene::SingleGene as CrossoverSingleGene;
pub use self::single_point::SinglePoint as CrossoverSinglePoint;
pub use self::uniform::Uniform as CrossoverUniform;
pub use self::wrapper::Wrapper as CrossoverWrapper;
use crate::genotype::EvolveGenotype;
use crate::strategy::evolve::{EvolveConfig, EvolveState};
use crate::strategy::StrategyReporter;
use rand::Rng;
use std::cmp::Ordering;
pub trait Crossover: Clone + Send + Sync + std::fmt::Debug {
fn call<G: EvolveGenotype, R: Rng, SR: StrategyReporter<Genotype = G>>(
&mut self,
genotype: &mut G,
state: &mut EvolveState<G>,
config: &EvolveConfig,
reporter: &mut SR,
rng: &mut R,
);
fn prepare_population<G: EvolveGenotype>(
&mut self,
genotype: &mut G,
state: &mut EvolveState<G>,
config: &EvolveConfig,
) -> usize {
let population_size = state.population.size();
match config.target_population_size.cmp(&population_size) {
Ordering::Greater => {
let parent_survivors =
(config.target_population_size - population_size).min(population_size);
genotype.chromosome_cloner_range(
&mut state.population.chromosomes,
0..parent_survivors,
);
}
Ordering::Less => {
eprintln!(
"Crossover: population-size {} is more than target-population-size {}, this should never happen",
population_size,
config.target_population_size
);
genotype.chromosome_destructor_truncate(
&mut state.population.chromosomes,
config.target_population_size,
);
}
Ordering::Equal => (),
}
population_size.min(config.target_population_size)
}
fn require_crossover_indexes(&self) -> bool {
false
}
fn require_crossover_points(&self) -> bool {
false
}
}