@@ 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)
})
}