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
use crate::{ genetic_algorithm::operators::mating_selection::MatingSelection, quality_comparator::QualityComparator, }; use mop_blocks::{ mph::{MphOrRef, MphOrs}, Obj, }; use num_traits::Zero; use rand::{distributions::uniform::SampleUniform, rngs::StdRng, Rng, SeedableRng}; #[derive(Clone, Debug, Default)] pub struct Tournament<QC> { n: usize, quality_comparator: QC, } impl<QC> Tournament<QC> { pub fn new(n: usize, quality_comparator: QC) -> Self { assert!(n > 0); Tournament { n, quality_comparator } } } impl<QC, O, OR, S> MatingSelection<[O], MphOrs<OR, S>> for Tournament<QC> where QC: for<'a> QualityComparator<[O], MphOrRef<'a, OR, S>>, O: Obj<OR, S>, OR: Copy + PartialOrd + SampleUniform + Zero, S: Clone, { fn mating_selection( &self, objs: &[O], source: &mut MphOrs<OR, S>, destination: &mut MphOrs<OR, S>, filling_num: usize, ) { destination.clear(); let mut rng = StdRng::from_entropy(); while destination.len() < filling_num { let mut winner = source.get(rng.gen_range(0, source.len())); for _ in 1..self.n { let current = source.get(rng.gen_range(0, source.len())); if self.quality_comparator.is_better(objs, ¤t, &winner) { winner = current; } } destination .constructor() .copy_result(&winner) .commit(**winner.objs_avg(), (*winner.solution()).clone()); } } }