~ruther/ctu-fee-eoa

3c081da6511c161b80e42cbfc735aee68f61298d — Rutherther a month ago b5a1a3a
refactor: use evaluated population in selection
1 files changed, 29 insertions(+), 37 deletions(-)

M env/src/selection.rs
M env/src/selection.rs => env/src/selection.rs +29 -37
@@ 1,14 1,13 @@
// pub struct EvaluatedChromosome<TInput, TResult> {
//     chromosome: TInput,
//     evaluation: TResult,
// }
use rand::{seq::IteratorRandom, Rng, RngCore};

use rand::{Rng, RngCore};
use crate::{comparison::BetterThanOperator, replacement::EvaluatedPopulation};

use crate::comparison::BetterThanOperator;

pub trait Selection<T> {
    fn select(&mut self, count: usize, evaluations: &Vec<T>, better_than: &dyn BetterThanOperator<T>) -> impl Iterator<Item = usize>;
pub trait Selection<TChromosome, TResult> {
    fn select(&mut self,
              count: usize,
              evaluations: &EvaluatedPopulation<TChromosome, TResult>,
              better_than: &dyn BetterThanOperator<TResult>
    ) -> impl Iterator<Item = usize>;
}

pub struct TournamentSelection {


@@ 29,8 28,16 @@ impl TournamentSelection {
        }
    }

    fn tournament<T: PartialOrd>(&mut self, idxs: &mut Vec<usize>, evaluations: &Vec<T>, better_than: &dyn BetterThanOperator<T>) -> usize {
        idxs.sort_by(|&i, &j| better_than.ordering(&evaluations[i], &evaluations[j]));
    fn tournament<TChromosome, TResult>(
        &mut self,
        idxs: &mut Vec<usize>,
        evaluations: &EvaluatedPopulation<TChromosome, TResult>,
        better_than: &dyn BetterThanOperator<TResult>
    ) -> usize {
        idxs.sort_by(|&i, &j| better_than.ordering(
            &evaluations.population[i].evaluation,
            &evaluations.population[j].evaluation)
        );

        let mut p_selector = self.rng.random_range(0.0..=1.0f64);
        let p = self.p;


@@ 56,34 63,19 @@ impl TournamentSelection {
    }
}

impl<T: Ord> Selection<T> for TournamentSelection {
    fn select(&mut self, count: usize, evaluations: &Vec<T>, better_than: &dyn BetterThanOperator<T>) -> impl Iterator<Item = usize> {
        // 1. Rank
        // fn rank<T: Ord>(l: &Vec<T>) -> Vec<usize> {
        //     let mut indices = (0..l.len()).collect::<Vec<_>>();
        //     let mut ranks = vec![0; l.len()];

        //     // argsort...
        //     indices.sort_by_key(|&i| &l[i]);

        //     for (rank, idx) in indices.into_iter().enumerate() {
        //         ranks[idx] = rank;
        //     }

        //     ranks
        // }

        // let ranks = rank(evaluations);

        // 2. Let's choose k random 'count' times
        // let mut already_selected = vec![false; evaluations.len()];

impl<TChromosome, TResult> Selection<TChromosome, TResult> for TournamentSelection {
    fn select(
        &mut self,
        count: usize,
        evaluations: &EvaluatedPopulation<TChromosome, TResult>,
        better_than: &dyn BetterThanOperator<TResult>
    ) -> impl Iterator<Item = usize> {
        // Let's reuse a single vector for the indices
        let mut k_selected_idxs = vec![0; self.k];
        (0..count).map(move |_| {
            for selected_idx in k_selected_idxs.iter_mut() {
                *selected_idx = self.rng.random_range(0..evaluations.len());
            }

            // Choose k. Do not care if already selected previously.
            (0..evaluations.population.len()).choose_multiple_fill(&mut self.rng, &mut k_selected_idxs);
            // Tournament between the k
            self.tournament(&mut k_selected_idxs, evaluations, better_than)
        })
    }