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
use std::{fmt::Debug, iter::Sum, ops::AddAssign}; use mop_blocks::mp::mphos::Morhos; use num_traits::Zero; use rand::{distributions::uniform::SampleUniform, thread_rng, Rng}; use genetic_algorithm::operators::mating_selection::MatingSelection; #[derive(Clone, Debug, Default)] pub struct RouletteWheel {} impl RouletteWheel { pub fn new() -> Self { RouletteWheel {} } } impl<N, V> MatingSelection<N, V> for RouletteWheel where N: AddAssign + Copy + Debug + PartialOrd + SampleUniform + Sum + Zero, V: Copy + Debug, { fn mating_selection( &mut self, source: &mut Morhos<N, V>, pool: &mut Morhos<N, V>, filling_num: usize, ) { pool.clear(); let mut rng = thread_rng(); let fitness_sum = source.iter().map(|x| *x.objs_avg()).sum(); while pool.len() < filling_num { let fitness_threshold = rng.gen_range(N::zero(), fitness_sum); let mut partial_fitness_sum = N::zero(); for opt_result in source.iter() { partial_fitness_sum += *opt_result.objs_avg(); if partial_fitness_sum >= fitness_threshold { pool.append_result(opt_result); break; } } } } }