~ruther/ctu-fee-eoa

ref: 25d837808d070d0baa6c048939db0e8ece3dfa8f ctu-fee-eoa/codes/eoa_lib/src/pairing.rs -rw-r--r-- 2.0 KiB
25d83780 — Rutherther tests(tsp): adapt to new binarystring -> node permutation implementation 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
68
69
use std::marker::PhantomData;

use nalgebra::{Const, OVector, SVector};

use crate::replacement::EvaluatedPopulation;

pub type ParentPairing<const D: usize> = OVector<usize, Const<D>>;

pub trait Pairing<const D: usize> {
    type Chromosome;
    type Out;

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

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<2> for AdjacentPairing<TChromosome, TOutput> {
    type Chromosome = TChromosome;
    type Out = TOutput;

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

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

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

    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(ParentPairing::<2>::new(first, second))
            },
            // Only one element remaining, return it and the previous one
            (Some(first), _) => Some(ParentPairing::<2>::new(first, self.1)),
            (None, Some(_)) => panic!("Iterators cannot return something after they return none."),
            // No more elements
            _ => None
        }
    }
}