avx_async/
genomic.rs

1//! Genetic Algorithm Optimization
2//!
3//! Evolutionary algorithms for runtime optimization
4
5use std::sync::{Arc, Mutex};
6
7/// Genetic algorithm for runtime configuration optimization
8#[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    /// Evaluate fitness of all genomes
42    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    /// Evolve to next generation
53    pub fn evolve(&self) {
54        let mut population = self.population.lock().unwrap();
55        let mut generation = self.generation.lock().unwrap();
56
57        // Sort by fitness (descending)
58        population.sort_by(|a, b| b.fitness.partial_cmp(&a.fitness).unwrap());
59
60        // Keep top 20% (elitism)
61        let elite_count = self.population_size / 5;
62        let elite = population[..elite_count].to_vec();
63
64        // Generate new population
65        let mut new_population = elite.clone();
66
67        while new_population.len() < self.population_size {
68            // Select parents (tournament selection)
69            let parent1 = &population[0]; // Best
70            let parent2 = &population[1]; // Second best
71
72            // Crossover
73            let mut child = self.crossover(parent1, parent2);
74
75            // Mutation
76            self.mutate(&mut child);
77
78            new_population.push(child);
79        }
80
81        *population = new_population;
82        *generation += 1;
83    }
84
85    /// Get best genome
86    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    /// Get current generation
94    pub fn generation(&self) -> usize {
95        *self.generation.lock().unwrap()
96    }
97
98    /// Get optimization statistics
99    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