@@ 1,19 1,34 @@
use rand::{seq::IteratorRandom, RngCore};
+use std::fmt::Debug;
use crate::{comparison::BetterThanOperator, fitness::FitnessFunction, selection::{Selection, TournamentSelection}};
-#[derive(Clone)]
+fn extract_by_indices<T>(mut x: Vec<T>, mut idxs: Vec<usize>) -> Vec<T> {
+ idxs.sort_unstable_by(|a, b| b.cmp(a));
+
+ let mut result = Vec::with_capacity(idxs.len());
+ for idx in idxs {
+ if idx < x.len() {
+ result.push(x.swap_remove(idx));
+ }
+ }
+
+ result.reverse();
+ result
+}
+
+#[derive(Clone, Debug)]
pub struct Population<TChromosome> {
population: Vec<TChromosome>
}
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct EvaluatedChromosome<TChromosome, TResult> {
pub chromosome: TChromosome,
pub evaluation: TResult,
}
-#[derive(Clone)]
+#[derive(Clone, Debug)]
pub struct EvaluatedPopulation<TChromosome, TResult> {
pub population: Vec<EvaluatedChromosome<TChromosome, TResult>>
}
@@ 25,6 40,10 @@ impl<TChromosome> Population<TChromosome> {
}
}
+ pub fn from_iterator(iter: impl Iterator<Item = TChromosome>) -> Self {
+ Self::from_vec(iter.collect())
+ }
+
pub fn evaluate<T: FitnessFunction<In = TChromosome>>(self, func: &T) -> Result<EvaluatedPopulation<TChromosome, T::Out>, T::Err> {
EvaluatedPopulation::evaluate(
self.population,
@@ 122,6 141,39 @@ pub trait Replacement<TChromosome, TResult> {
) -> EvaluatedPopulation<TChromosome, TResult>;
}
+pub struct BestReplacement;
+impl BestReplacement {
+ pub fn new() -> Self {
+ Self
+ }
+}
+
+impl<TChromosome, TResult: Copy + Debug> Replacement<TChromosome, TResult> for BestReplacement {
+ fn replace(
+ &mut self,
+ parents_evaluations: EvaluatedPopulation<TChromosome, TResult>,
+ offsprings_evaluations: EvaluatedPopulation<TChromosome, TResult>,
+ better_than: &dyn BetterThanOperator<TResult>
+ ) -> EvaluatedPopulation<TChromosome, TResult> {
+ let count = parents_evaluations.population.len();
+ let mut population = parents_evaluations;
+ population.join(offsprings_evaluations);
+
+ let mut idxs = (0..population.population.len())
+ .collect::<Vec<_>>();
+ idxs.sort_unstable_by(|&i, &j| better_than.ordering(
+ &population.population[i].evaluation,
+ &population.population[j].evaluation)
+ );
+
+ idxs.truncate(count);
+
+ EvaluatedPopulation::from_vec(
+ extract_by_indices(population.deconstruct(), idxs)
+ )
+ }
+}
+
pub struct GenerationalReplacement;
impl<TInput, TResult> Replacement<TInput, TResult> for GenerationalReplacement {
fn replace(