use crate::configuration::ProblemSolving;
use crate::operations::{Crossover, GaussianParams, Mutation};
#[derive(Debug, Clone, PartialEq)]
pub enum AlpsAgeScheme {
Linear,
Fibonacci,
Polynomial,
}
#[derive(Debug, Clone)]
pub struct AlpsConfiguration {
pub n_layers: usize,
pub layer_size: usize,
pub age_scheme: AlpsAgeScheme,
pub age_gap: usize,
pub injection_interval: usize,
pub max_generations: usize,
pub crossover: Crossover,
pub mutation: Mutation,
pub problem_solving: ProblemSolving,
pub fitness_target: Option<f64>,
}
impl Default for AlpsConfiguration {
fn default() -> Self {
Self {
n_layers: 6,
layer_size: 20,
age_scheme: AlpsAgeScheme::Fibonacci,
age_gap: 5,
injection_interval: 10,
max_generations: 1000,
crossover: Crossover::Uniform,
mutation: Mutation::Gaussian(GaussianParams { sigma: Some(0.1) }),
problem_solving: ProblemSolving::Minimization,
fitness_target: None,
}
}
}
impl AlpsConfiguration {
pub fn with_n_layers(mut self, n: usize) -> Self {
self.n_layers = n;
self
}
pub fn with_layer_size(mut self, n: usize) -> Self {
self.layer_size = n;
self
}
pub fn with_age_scheme(mut self, scheme: AlpsAgeScheme) -> Self {
self.age_scheme = scheme;
self
}
pub fn with_age_gap(mut self, gap: usize) -> Self {
self.age_gap = gap;
self
}
pub fn with_injection_interval(mut self, interval: usize) -> Self {
self.injection_interval = interval;
self
}
pub fn with_max_generations(mut self, n: usize) -> Self {
self.max_generations = n;
self
}
pub fn with_crossover(mut self, c: Crossover) -> Self {
self.crossover = c;
self
}
pub fn with_mutation(mut self, m: Mutation) -> Self {
self.mutation = m;
self
}
pub fn with_problem_solving(mut self, ps: ProblemSolving) -> Self {
self.problem_solving = ps;
self
}
pub fn with_fitness_target(mut self, t: f64) -> Self {
self.fitness_target = Some(t);
self
}
pub fn max_ages(&self) -> Vec<usize> {
(0..self.n_layers)
.map(|i| {
let factor = match self.age_scheme {
AlpsAgeScheme::Linear => i + 1,
AlpsAgeScheme::Fibonacci => fibonacci(i + 2),
AlpsAgeScheme::Polynomial => (i + 1) * (i + 1),
};
factor * self.age_gap
})
.collect()
}
}
pub fn fibonacci(n: usize) -> usize {
match n {
0 => 0,
1 | 2 => 1,
_ => {
let (mut a, mut b) = (1usize, 1usize);
for _ in 2..n {
(a, b) = (b, a.saturating_add(b));
}
b
}
}
}