use crate::traits::ChromosomeT;
use log::{debug, trace};
use rand::Rng;
use rayon::prelude::*;
pub fn tournament<U>(
chromosomes: &[U],
couples: usize,
_number_of_threads: usize,
) -> Vec<(usize, usize)>
where
U: ChromosomeT + Send + Sync + 'static + Clone,
{
tournament_impl(chromosomes, couples)
}
fn tournament_impl<U>(chromosomes: &[U], couples: usize) -> Vec<(usize, usize)>
where
U: ChromosomeT + Send + Sync + 'static + Clone,
{
debug!(target="selection_events", method="tournament"; "Starting tournament selection");
let couples = if couples * 2 > chromosomes.len() {
chromosomes.len() / 2
} else {
couples
};
let total_contestants = couples * 2;
let winners: Vec<usize> = (0..total_contestants)
.into_par_iter()
.map(|_| {
let mut rng = crate::rng::make_rng();
let index_1 = rng.random_range(0..chromosomes.len());
let index_2 = rng.random_range(0..chromosomes.len());
trace!(target="selection_events", method="tournament"; "Tournament between {} and {}", index_1, index_2);
if chromosomes[index_1].fitness() >= chromosomes[index_2].fitness() {
index_1
} else {
index_2
}
})
.collect();
let mut mating = Vec::new();
for chunk in winners.chunks(2) {
if chunk.len() == 2 {
mating.push((chunk[0], chunk[1]));
trace!(target="selection_events", method="tournament"; "Mating index 1: {} - index 2: {}", chunk[0], chunk[1]);
}
}
debug!(target="selection_events", method="tournament"; "Tournament selection finished");
mating
}