1use crate::dna::{DigitalDNA, Mutation, DNAError};
7use crate::tron::TRON;
8use serde::{Deserialize, Serialize};
9use std::time::{SystemTime, UNIX_EPOCH};
10
11#[derive(Debug, Clone)]
13pub struct EvolutionEngine {
14 pub current_cycle: u64,
16 pub selection_pressure: f64,
18 pub mutation_rate: f64,
20 pub evolution_history: Vec<EvolutionEvent>,
22 pub fitness_stats: FitnessStats,
24 pub parameters: EvolutionParameters,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub enum MutationType {
31 Beneficial,
33 Neutral,
35 Harmful,
37 Adaptive,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
43pub enum SelectionPressure {
44 Natural,
46 Sexual,
48 Environmental,
50 Competitive,
52 Artificial,
54}
55
56#[derive(Debug, Clone, Serialize, Deserialize)]
58pub struct EvolutionEvent {
59 pub event_id: String,
61 pub organism_id: String,
63 pub cycle: u64,
65 pub mutation: Mutation,
67 pub fitness_before: f64,
69 pub fitness_after: f64,
71 pub selection_pressure: f64,
73 pub timestamp: u64,
75 pub outcome: EvolutionOutcome,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize)]
81pub enum EvolutionOutcome {
82 Success,
84 Failed,
86 Extinct,
88 Speciation,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct EvolutionParameters {
95 pub base_mutation_rate: f64,
97 pub max_mutations_per_cycle: usize,
99 pub survival_threshold: f64,
101 pub reproduction_threshold: f64,
103 pub adaptation_factor: f64,
105 pub sexual_selection_strength: f64,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct FitnessStats {
112 pub average_fitness: f64,
114 pub max_fitness: f64,
116 pub min_fitness: f64,
118 pub fitness_variance: f64,
120 pub organism_count: usize,
122}
123
124impl EvolutionEngine {
125 pub fn new() -> Result<Self, EvolutionError> {
127 Ok(EvolutionEngine {
128 current_cycle: 0,
129 selection_pressure: 0.5,
130 mutation_rate: 0.01,
131 evolution_history: Vec::new(),
132 fitness_stats: FitnessStats::new(),
133 parameters: EvolutionParameters::default(),
134 })
135 }
136
137 pub fn evolve_organism(&mut self, organism: &mut TRON) -> Result<EvolutionEvent, EvolutionError> {
139 let fitness_before = organism.dna.fitness;
140
141 if fitness_before < self.parameters.survival_threshold {
143 return Err(EvolutionError::InsufficientFitness(fitness_before));
144 }
145
146 let mutation = self.generate_mutation(&organism.dna)?;
148
149 organism.dna.mutate(mutation.clone())
151 .map_err(|e| EvolutionError::MutationFailed(e.to_string()))?;
152
153 let fitness_after = organism.dna.fitness;
154
155 let event = EvolutionEvent {
157 event_id: uuid::Uuid::new_v4().to_string(),
158 organism_id: organism.id.clone(),
159 cycle: self.current_cycle,
160 mutation,
161 fitness_before,
162 fitness_after,
163 selection_pressure: self.selection_pressure,
164 timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
165 outcome: if fitness_after > fitness_before {
166 EvolutionOutcome::Success
167 } else {
168 EvolutionOutcome::Failed
169 },
170 };
171
172 self.evolution_history.push(event.clone());
173 self.fitness_stats.update_fitness(fitness_after);
174
175 Ok(event)
176 }
177
178 fn generate_mutation(&self, dna: &DigitalDNA) -> Result<Mutation, EvolutionError> {
180 let mutation_type = if dna.fitness > 0.8 {
182 MutationType::Beneficial
183 } else if dna.fitness < 0.3 {
184 MutationType::Adaptive
185 } else {
186 MutationType::Neutral
187 };
188
189 match mutation_type {
191 MutationType::Beneficial => {
192 if rand::random::<f64>() < 0.1 {
194 Ok(Mutation::KeyEvolution {
195 old_generation: dna.keypair.key_generation,
196 new_generation: dna.keypair.key_generation + 1,
197 timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
198 })
199 } else {
200 Ok(dna.generate_random_mutation())
201 }
202 },
203 MutationType::Adaptive => {
204 Ok(Mutation::Duplication {
206 start: rand::random::<usize>() % dna.sequence.len(),
207 end: rand::random::<usize>() % dna.sequence.len(),
208 insert_at: rand::random::<usize>() % dna.sequence.len(),
209 timestamp: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
210 })
211 },
212 _ => Ok(dna.generate_random_mutation()),
213 }
214 }
215
216 pub fn apply_selection_pressure(&mut self, organisms: &mut Vec<TRON>) -> Result<Vec<String>, EvolutionError> {
218 let mut eliminated = Vec::new();
219
220 organisms.sort_by(|a, b| b.dna.fitness.partial_cmp(&a.dna.fitness).unwrap());
222
223 let elimination_threshold = self.selection_pressure;
225 let mut to_eliminate = Vec::new();
226
227 for organism in organisms.iter() {
228 if organism.dna.fitness < elimination_threshold {
229 to_eliminate.push(organism.id.clone());
230 }
231 }
232
233 organisms.retain(|o| !to_eliminate.contains(&o.id));
235 eliminated.extend(to_eliminate);
236
237 self.update_population_stats(organisms);
239
240 Ok(eliminated)
241 }
242
243 fn update_population_stats(&mut self, organisms: &[TRON]) {
245 if organisms.is_empty() {
246 return;
247 }
248
249 let fitnesses: Vec<f64> = organisms.iter().map(|o| o.dna.fitness).collect();
250
251 self.fitness_stats.organism_count = organisms.len();
252 self.fitness_stats.average_fitness = fitnesses.iter().sum::<f64>() / organisms.len() as f64;
253 self.fitness_stats.max_fitness = fitnesses.iter().cloned().fold(0.0, f64::max);
254 self.fitness_stats.min_fitness = fitnesses.iter().cloned().fold(f64::INFINITY, f64::min);
255
256 let mean = self.fitness_stats.average_fitness;
258 let variance = fitnesses.iter()
259 .map(|f| (f - mean).powi(2))
260 .sum::<f64>() / organisms.len() as f64;
261 self.fitness_stats.fitness_variance = variance;
262 }
263
264 pub fn get_stats(&self) -> EvolutionStats {
266 EvolutionStats {
267 current_cycle: self.current_cycle,
268 total_events: self.evolution_history.len(),
269 successful_evolutions: self.evolution_history.iter()
270 .filter(|e| matches!(e.outcome, EvolutionOutcome::Success))
271 .count(),
272 failed_evolutions: self.evolution_history.iter()
273 .filter(|e| matches!(e.outcome, EvolutionOutcome::Failed))
274 .count(),
275 average_fitness: self.fitness_stats.average_fitness,
276 max_fitness: self.fitness_stats.max_fitness,
277 min_fitness: self.fitness_stats.min_fitness,
278 selection_pressure: self.selection_pressure,
279 mutation_rate: self.mutation_rate,
280 }
281 }
282
283 pub fn advance_cycle(&mut self) {
285 self.current_cycle += 1;
286
287 if self.fitness_stats.average_fitness > 0.8 {
289 self.mutation_rate *= 0.9; } else if self.fitness_stats.average_fitness < 0.3 {
291 self.mutation_rate *= 1.1; }
293
294 self.mutation_rate = self.mutation_rate.max(0.001).min(0.1);
296 }
297}
298
299#[derive(Debug, Clone, Serialize, Deserialize)]
301pub struct EvolutionStats {
302 pub current_cycle: u64,
303 pub total_events: usize,
304 pub successful_evolutions: usize,
305 pub failed_evolutions: usize,
306 pub average_fitness: f64,
307 pub max_fitness: f64,
308 pub min_fitness: f64,
309 pub selection_pressure: f64,
310 pub mutation_rate: f64,
311}
312
313impl FitnessStats {
314 pub fn new() -> Self {
315 FitnessStats {
316 average_fitness: 0.0,
317 max_fitness: 0.0,
318 min_fitness: f64::INFINITY,
319 fitness_variance: 0.0,
320 organism_count: 0,
321 }
322 }
323
324 pub fn update_fitness(&mut self, fitness: f64) {
325 self.organism_count += 1;
326
327 if fitness > self.max_fitness {
328 self.max_fitness = fitness;
329 }
330
331 if fitness < self.min_fitness {
332 self.min_fitness = fitness;
333 }
334
335 self.average_fitness = ((self.average_fitness * (self.organism_count - 1) as f64) + fitness) / self.organism_count as f64;
337 }
338}
339
340impl Default for EvolutionParameters {
341 fn default() -> Self {
342 EvolutionParameters {
343 base_mutation_rate: 0.01,
344 max_mutations_per_cycle: 3,
345 survival_threshold: 0.1,
346 reproduction_threshold: 0.6,
347 adaptation_factor: 0.8,
348 sexual_selection_strength: 0.5,
349 }
350 }
351}
352
353#[derive(Debug, thiserror::Error)]
355pub enum EvolutionError {
356 #[error("Insufficient fitness for evolution: {0}")]
357 InsufficientFitness(f64),
358 #[error("Mutation failed: {0}")]
359 MutationFailed(String),
360 #[error("Selection pressure too high: {0}")]
361 SelectionPressureTooHigh(f64),
362 #[error("Population extinct")]
363 PopulationExtinct,
364 #[error("Evolution cycle limit reached")]
365 CycleLimitReached,
366 #[error("DNA error: {0}")]
367 DNA(#[from] DNAError),
368}
369
370#[cfg(test)]
371mod tests {
372 use super::*;
373 use crate::dna::DigitalDNA;
374
375 #[test]
376 fn test_evolution_engine_creation() {
377 let engine = EvolutionEngine::new().unwrap();
378 assert_eq!(engine.current_cycle, 0);
379 assert_eq!(engine.selection_pressure, 0.5);
380 assert_eq!(engine.mutation_rate, 0.01);
381 }
382
383 #[test]
384 fn test_organism_evolution() {
385 let mut engine = EvolutionEngine::new().unwrap();
386 let mut organism = TRON::create_new().unwrap();
387
388 let initial_fitness = organism.dna.fitness;
389 let initial_generation = organism.dna.generation;
390
391 let event = engine.evolve_organism(&mut organism).unwrap();
392
393 assert_eq!(event.organism_id, organism.id);
394 assert_eq!(event.fitness_before, initial_fitness);
395 assert_eq!(organism.dna.generation, initial_generation + 1);
396 assert_eq!(engine.evolution_history.len(), 1);
397 }
398
399 #[test]
400 fn test_selection_pressure() {
401 let mut engine = EvolutionEngine::new().unwrap();
402 let mut organisms = Vec::new();
403
404 for i in 0..10 {
406 let mut organism = TRON::create_new().unwrap();
407 organism.dna.fitness = i as f64 / 10.0;
408 organisms.push(organism);
409 }
410
411 engine.selection_pressure = 0.5;
412 let eliminated = engine.apply_selection_pressure(&mut organisms).unwrap();
413
414 assert!(eliminated.len() > 0);
416 assert!(organisms.len() < 10);
417
418 for organism in &organisms {
420 assert!(organism.dna.fitness >= 0.5);
421 }
422 }
423
424 #[test]
425 fn test_fitness_stats() {
426 let mut stats = FitnessStats::new();
427
428 stats.update_fitness(0.8);
429 stats.update_fitness(0.6);
430 stats.update_fitness(0.9);
431
432 assert_eq!(stats.organism_count, 3);
433 assert_eq!(stats.max_fitness, 0.9);
434 assert_eq!(stats.min_fitness, 0.6);
435 assert!((stats.average_fitness - 0.7667).abs() < 0.01);
436 }
437
438 #[test]
439 fn test_evolution_cycle_advance() {
440 let mut engine = EvolutionEngine::new().unwrap();
441 let initial_cycle = engine.current_cycle;
442
443 engine.advance_cycle();
444
445 assert_eq!(engine.current_cycle, initial_cycle + 1);
446 }
447
448 #[test]
449 fn test_mutation_rate_adjustment() {
450 let mut engine = EvolutionEngine::new().unwrap();
451
452 engine.fitness_stats.average_fitness = 0.9;
454 let initial_rate = engine.mutation_rate;
455
456 engine.advance_cycle();
457
458 assert!(engine.mutation_rate < initial_rate);
459
460 engine.fitness_stats.average_fitness = 0.2;
462 let current_rate = engine.mutation_rate;
463
464 engine.advance_cycle();
465
466 assert!(engine.mutation_rate > current_rate);
467 }
468}