~ruther/ctu-fee-eoa

ref: 8d13c2754c8d1738299b07c27193f6ecd2ddaf95 ctu-fee-eoa/codes/eoa_lib/src/pairing.rs -rw-r--r-- 1.9 KiB
8d13c275 — Rutherther chore: move env to codes/eoa_lib a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
        }
    }
}