1pub mod botzmann;
2pub mod elite;
3pub mod linear_rank;
4pub mod nsga2;
5pub mod random_selector;
6pub mod rank;
7pub mod roulette;
8pub mod steady_state;
9pub mod stochastic_sampling;
10pub mod tournament;
11
12use radiate_core::random_provider;
13
14pub use botzmann::BoltzmannSelector;
15pub use elite::EliteSelector;
16pub use linear_rank::LinearRankSelector;
17pub use nsga2::{NSGA2Selector, TournamentNSGA2Selector};
18pub use random_selector::RandomSelector;
19pub use rank::RankSelector;
20pub use roulette::RouletteSelector;
21pub use steady_state::SteadyStateSelector;
22pub use stochastic_sampling::StochasticUniversalSamplingSelector;
23pub use tournament::TournamentSelector;
24
25pub(crate) struct ProbabilityWheelIterator<'a> {
32 probabilities: &'a [f32],
33 total: f32,
34 max_index: usize,
35 current: usize,
36}
37
38impl<'a> ProbabilityWheelIterator<'a> {
39 pub fn new(probabilities: &'a [f32], max_index: usize) -> Self {
40 let total = probabilities.iter().sum();
41 Self {
42 probabilities,
43 total,
44 max_index,
45 current: 0,
46 }
47 }
48}
49
50impl Iterator for ProbabilityWheelIterator<'_> {
51 type Item = usize;
52
53 fn next(&mut self) -> Option<Self::Item> {
54 if self.current >= self.max_index {
61 return None;
62 }
63
64 let mut value = random_provider::random::<f32>() * self.total;
65 let mut index = 0;
66
67 for (i, &prob) in self.probabilities.iter().enumerate() {
69 value -= prob;
70 if value <= 0.0 {
71 index = i;
72 break;
73 }
74 }
75
76 self.current += 1;
77 Some(index)
78 }
79}