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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
use crateGeneticEngineBuilder;
use crateContext;
use crateEngineMessage;
use crateEngineIterator;
use cratePipeline;
use crate::;
use crate::;
use Engine;
use Result;
/// The [GeneticEngine] is the core component of the Radiate library's genetic algorithm implementation.
/// The engine is designed to be fast, flexible and extensible, allowing users to
/// customize various aspects of the genetic algorithm to suit their specific needs.
///
/// Essentially, it is a high-level abstraction that orchestrates all aspects of the genetic algorithm. It is
/// responsible for managing the population of individuals, evaluating the fitness of each individual,
/// selecting the individuals that will survive to the next generation, and creating the next generation through
/// crossover and mutation.
///
/// # Examples
/// ``` no_run
/// use radiate_engines::*;
///
/// // Define a codec that encodes and decodes individuals in the population, in this case using floats.
/// let codec = FloatCodec::matrix(1, 5, 0.0..100.0);
/// // This codec will encode Genotype instances with 1 Chromosome and 5 FloatGenes,
/// // with random alleles between 0.0 and 100.0. It will decode into a Vec<Vec<f32>>.
/// // eg: [[1.0, 2.0, 3.0, 4.0, 5.0]]
///
/// // Create a new instance of the genetic engine with the given codec.
/// let mut engine = GeneticEngine::builder()
/// .codec(codec)
/// .minimizing()
/// .population_size(150)
/// .max_age(15)
/// .offspring_fraction(0.5)
/// .offspring_selector(BoltzmannSelector::new(4_f32))
/// .survivor_selector(TournamentSelector::new(3))
/// .alter(alters![
/// ArithmeticMutator::new(0.01),
/// MeanCrossover::new(0.5)
/// ])
/// .fitness_fn(|genotype: Vec<Vec<f32>>| {
/// genotype.iter().fold(0.0, |acc, chromosome| {
/// acc + chromosome.iter().sum::<f32>()
/// })
/// })
/// .build();
///
/// // Run the genetic algorithm until the score of the best individual is 0, then return the result.
/// let result = engine.run(|output| output.score().as_i32() == 0);
/// ```
///
/// # Type Parameters
/// - `C`: The type of the chromosome used in the genotype, which must implement the [Chromosome] trait.
/// - `T`: The type of the phenotype produced by the genetic algorithm, which must be `Clone`, `Send`, and `static`.
/// Implementation of the [Engine] trait for [GeneticEngine].
///
/// This implementation provides the core evolutionary logic, advancing the
/// population through one complete generation cycle. Each call to `next()`
/// represents one generation of evolution, including fitness evaluation,
/// selection, reproduction, and population replacement.
///
/// # Evolutionary Cycle
///
/// Each generation follows this sequence:
/// 1. **Event Emission**: Start of epoch events
/// 2. **Pipeline Execution**: Run evolutionary operators
/// 3. **Metrics Collection**: Record timing and performance data
/// 4. **Best Individual Update**: Track improvements and best solutions
/// 5. **Event Completion**: End of epoch events
/// 6. **Generation Advancement**: Increment generation counter
///
/// # Performance Optimizations
///
/// - **Efficient Metrics**: Metrics are updated incrementally to minimize overhead
/// - **Event Batching**: Events are emitted efficiently without blocking execution
/// - **Pipeline Optimization**: Evolutionary operators are executed in optimized sequences
/// Custom drop implementation for proper cleanup and event emission.
///
/// When the engine is dropped, it emits a stop event to notify any listeners
/// that the evolutionary process has ended. This allows external systems to
/// perform cleanup operations or finalize results.
///
/// # Event Emission
///
/// The stop event includes the final context state, allowing listeners to:
/// - Record final metrics and statistics
/// - Save final population state
/// - Perform cleanup operations
/// - Generate final reports
/// - Integrate with external systems