~ruther/ctu-fee-eoa

d4df3887a92f94774475ea5fafb33408e1ba10a7 — Rutherther a month ago 1f3a772
feat: add pairing of parents
2 files changed, 68 insertions(+), 0 deletions(-)

M env/src/main.rs
A env/src/pairing.rs
M env/src/main.rs => env/src/main.rs +1 -0
@@ 1,4 1,5 @@
pub mod fitness;
pub mod pairing;
pub mod crossover;
pub mod bounded;
pub mod selection;

A env/src/pairing.rs => env/src/pairing.rs +67 -0
@@ 0,0 1,67 @@
use std::marker::PhantomData;

use crate::replacement::EvaluatedPopulation;

pub type ParentPairing = (usize, usize);

pub trait Pairing {
    type Chromosome;
    type Out;

    fn pair<T: Iterator<Item = usize>>(
        &mut self,
        population: &EvaluatedPopulation<Self::Chromosome, Self::Out>,
        parents: T
    ) -> impl Iterator<Item = ParentPairing>;
}

pub struct AdjacentPairing<TChromosome, TOutput> {
    _phantom1: PhantomData<TChromosome>,
    _phantom2: PhantomData<TOutput>,
}

impl<TChromosome, TOutput> AdjacentPairing<TChromosome, TOutput> {
    pub fn new() -> Self {
        Self {
            _phantom1: PhantomData,
            _phantom2: PhantomData,
        }
    }
}

impl<TChromosome, TOutput> Pairing for AdjacentPairing<TChromosome, TOutput> {
    type Chromosome = TChromosome;
    type Out = TOutput;

    fn pair<T: Iterator<Item = usize>>(
        &mut self,
        _: &EvaluatedPopulation<Self::Chromosome, Self::Out>,
        parents: T
    ) -> impl Iterator<Item = ParentPairing> {
        AdjacentIterator(parents, 0)
    }
}

pub struct AdjacentIterator<T: Iterator<Item = usize>>(T, usize);

impl<T: Iterator<Item = usize>> Iterator for AdjacentIterator<T> {
    type Item = ParentPairing;

    fn next(&mut self) -> Option<Self::Item> {
        let first = self.0.next();
        let second = self.0.next();

        match (first, second) {
            // Still two elements left, return them
            (Some(first), Some(second)) => {
                self.1 = second; // Save previous
                Some((first, second))
            },
            // Only one element remaining, return it and the previous one
            (Some(first), _) => Some((first, self.1)),
            (None, Some(_)) => panic!("Iterators cannot return something after they return none."),
            // No more elements
            _ => None
        }
    }
}