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;
                }
            }
        }
    }
}