1use std::sync::{Arc, Mutex};
6
7#[derive(Clone)]
9pub struct GeneticOptimizer {
10 population: Arc<Mutex<Vec<Genome>>>,
11 generation: Arc<Mutex<usize>>,
12 population_size: usize,
13 mutation_rate: f64,
14}
15
16#[derive(Clone, Debug)]
17pub struct Genome {
18 pub genes: Vec<f64>,
19 pub fitness: f64,
20}
21
22impl GeneticOptimizer {
23 pub fn new(population_size: usize, gene_count: usize, mutation_rate: f64) -> Self {
24 let population: Vec<Genome> = (0..population_size)
25 .map(|i| Genome {
26 genes: (0..gene_count)
27 .map(|j| ((i * 7919 + j * 3571) as f64 % 1000.0) / 1000.0)
28 .collect(),
29 fitness: 0.0,
30 })
31 .collect();
32
33 Self {
34 population: Arc::new(Mutex::new(population)),
35 generation: Arc::new(Mutex::new(0)),
36 population_size,
37 mutation_rate,
38 }
39 }
40
41 pub fn evaluate<F>(&self, fitness_fn: F)
43 where
44 F: Fn(&[f64]) -> f64,
45 {
46 let mut population = self.population.lock().unwrap();
47 for genome in population.iter_mut() {
48 genome.fitness = fitness_fn(&genome.genes);
49 }
50 }
51
52 pub fn evolve(&self) {
54 let mut population = self.population.lock().unwrap();
55 let mut generation = self.generation.lock().unwrap();
56
57 population.sort_by(|a, b| b.fitness.partial_cmp(&a.fitness).unwrap());
59
60 let elite_count = self.population_size / 5;
62 let elite = population[..elite_count].to_vec();
63
64 let mut new_population = elite.clone();
66
67 while new_population.len() < self.population_size {
68 let parent1 = &population[0]; let parent2 = &population[1]; let mut child = self.crossover(parent1, parent2);
74
75 self.mutate(&mut child);
77
78 new_population.push(child);
79 }
80
81 *population = new_population;
82 *generation += 1;
83 }
84
85 pub fn best(&self) -> Option<Genome> {
87 let population = self.population.lock().unwrap();
88 population.iter()
89 .max_by(|a, b| a.fitness.partial_cmp(&b.fitness).unwrap())
90 .cloned()
91 }
92
93 pub fn generation(&self) -> usize {
95 *self.generation.lock().unwrap()
96 }
97
98 pub fn stats(&self) -> GeneticStats {
100 let population = self.population.lock().unwrap();
101 let generation = *self.generation.lock().unwrap();
102
103 let avg_fitness = if !population.is_empty() {
104 population.iter().map(|g| g.fitness).sum::<f64>() / population.len() as f64
105 } else {
106 0.0
107 };
108
109 let best_fitness = population.iter()
110 .map(|g| g.fitness)
111 .max_by(|a, b| a.partial_cmp(b).unwrap())
112 .unwrap_or(0.0);
113
114 GeneticStats {
115 generation,
116 population_size: population.len(),
117 avg_fitness,
118 best_fitness,
119 mutation_rate: self.mutation_rate,
120 }
121 }
122
123 fn crossover(&self, parent1: &Genome, parent2: &Genome) -> Genome {
124 let gene_count = parent1.genes.len();
125 let crossover_point = gene_count / 2;
126
127 let mut genes = Vec::with_capacity(gene_count);
128 genes.extend_from_slice(&parent1.genes[..crossover_point]);
129 genes.extend_from_slice(&parent2.genes[crossover_point..]);
130
131 Genome { genes, fitness: 0.0 }
132 }
133
134 fn mutate(&self, genome: &mut Genome) {
135 for gene in &mut genome.genes {
136 if ((*gene * 1000.0) % 1.0) < self.mutation_rate {
137 *gene = ((*gene * 7919.0) % 1000.0) / 1000.0;
138 }
139 }
140 }
141}
142
143#[derive(Debug, Clone)]
144pub struct GeneticStats {
145 pub generation: usize,
146 pub population_size: usize,
147 pub avg_fitness: f64,
148 pub best_fitness: f64,
149 pub mutation_rate: f64,
150}
151
152impl std::fmt::Display for Genome {
153 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
154 write!(
155 f,
156 "Genome[genes={}, fitness={:.3}]",
157 self.genes.len(),
158 self.fitness
159 )
160 }
161}
162
163impl std::fmt::Display for GeneticStats {
164 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165 write!(
166 f,
167 "Gen{}: pop={}, avg={:.3}, best={:.3}",
168 self.generation, self.population_size, self.avg_fitness, self.best_fitness
169 )
170 }
171}
172
173
174
175
176