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 #[inline]
54 fn next(&mut self) -> Option<Self::Item> {
55 if self.current >= self.max_index {
62 return None;
63 }
64
65 let mut value = random_provider::random::<f32>() * self.total;
66 let mut index = 0;
67
68 for (i, prob) in self.probabilities.iter().enumerate() {
70 value -= prob;
71 if value <= 0.0 {
72 index = i;
73 break;
74 }
75 }
76
77 self.current += 1;
78 Some(index)
79 }
80}