use std::fmt;
use crate::chromosomes::ChromosomeLength;
use crate::extension::configuration::ExtensionConfiguration;
use crate::niching::configuration::NichingConfiguration;
use crate::operations::local_search::{
HillClimbingConfig, LocalSearch, LocalSearchApplicationStrategy, LocalSearchMode,
};
use crate::operations::{Crossover, Mutation, Selection, Survivor};
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ProblemSolving {
Minimization,
Maximization,
FixedFitness,
}
impl fmt::Display for ProblemSolving {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ProblemSolving::Minimization => write!(f, "Minimization"),
ProblemSolving::Maximization => write!(f, "Maximization"),
ProblemSolving::FixedFitness => write!(f, "FixedFitness"),
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SelectionConfiguration {
pub number_of_couples: usize,
pub method: Selection,
pub boltzmann_temperature: f64,
pub niche_radius: f64,
pub epsilon: f64,
}
impl Default for SelectionConfiguration {
fn default() -> Self {
SelectionConfiguration {
number_of_couples: 0,
method: Selection::Tournament,
boltzmann_temperature: 1.0,
niche_radius: 0.1,
epsilon: 0.0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CrossoverConfiguration {
pub number_of_points: Option<usize>,
pub probability_max: Option<f64>,
pub probability_min: Option<f64>,
pub method: Crossover,
pub sbx_eta: Option<f64>,
pub blend_alpha: Option<f64>,
pub arithmetic_alpha: Option<f64>,
pub undx_sigma_xi: Option<f64>,
pub undx_sigma_eta: Option<f64>,
pub pcx_sigma_eta: Option<f64>,
pub pcx_sigma_zeta: Option<f64>,
}
impl Default for CrossoverConfiguration {
fn default() -> Self {
CrossoverConfiguration {
number_of_points: None,
probability_max: None,
probability_min: None,
method: Crossover::Uniform,
sbx_eta: None,
blend_alpha: None,
arithmetic_alpha: None,
undx_sigma_xi: None,
undx_sigma_eta: None,
pcx_sigma_eta: None,
pcx_sigma_zeta: None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MutationConfiguration {
pub probability_max: Option<f64>,
pub probability_min: Option<f64>,
pub method: Mutation,
pub dynamic_mutation: bool,
pub target_cardinality: Option<f64>,
pub probability_step: Option<f64>,
}
impl Default for MutationConfiguration {
fn default() -> Self {
MutationConfiguration {
probability_max: None,
probability_min: None,
method: Mutation::Swap,
dynamic_mutation: false,
target_cardinality: None,
probability_step: None,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LimitConfiguration {
pub problem_solving: ProblemSolving,
pub max_generations: usize,
pub fitness_target: Option<f64>,
pub population_size: usize,
pub chromosome_length: ChromosomeLength,
}
impl Default for LimitConfiguration {
fn default() -> Self {
LimitConfiguration {
problem_solving: ProblemSolving::Minimization,
max_generations: 100,
fitness_target: None,
population_size: 0,
chromosome_length: ChromosomeLength::default(),
}
}
}
#[derive(Clone, Debug, Default, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SaveProgressConfiguration {
pub save_progress: bool,
pub save_progress_interval: usize,
pub save_progress_path: String,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LocalSearchConfiguration {
pub method: LocalSearch,
pub application_strategy: LocalSearchApplicationStrategy,
pub mode: LocalSearchMode,
pub hill_climbing: HillClimbingConfig,
}
impl Default for LocalSearchConfiguration {
fn default() -> Self {
Self {
method: LocalSearch::HillClimbing,
application_strategy: LocalSearchApplicationStrategy::AllOffspring,
mode: LocalSearchMode::Lamarckian,
hill_climbing: HillClimbingConfig::default(),
}
}
}
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct GaConfiguration {
pub(crate) adaptive_ga: bool,
pub(crate) number_of_threads: usize,
pub(crate) limit_configuration: LimitConfiguration,
pub(crate) selection_configuration: SelectionConfiguration,
pub(crate) crossover_configuration: CrossoverConfiguration,
pub(crate) mutation_configuration: MutationConfiguration,
pub(crate) survivor: Survivor,
pub(crate) save_progress_configuration: SaveProgressConfiguration,
pub(crate) elitism_count: usize,
pub(crate) stagnation_generations: Option<usize>,
pub(crate) convergence_threshold: Option<f64>,
pub(crate) max_duration_secs: Option<f64>,
pub(crate) niching_configuration: Option<NichingConfiguration>,
pub(crate) extension_configuration: Option<ExtensionConfiguration>,
pub(crate) rng_seed: Option<u64>,
pub(crate) crossover_portfolio: Option<Vec<Crossover>>,
pub(crate) mutation_portfolio: Option<Vec<Mutation>>,
pub(crate) aos_strategy: crate::aos::AosStrategy,
pub(crate) aos_reward_window: usize,
pub(crate) local_search_configuration: Option<LocalSearchConfiguration>,
pub(crate) length_penalty: Option<f64>,
}
impl Default for GaConfiguration {
fn default() -> Self {
GaConfiguration {
adaptive_ga: false,
number_of_threads: 1,
survivor: Survivor::Fitness,
limit_configuration: LimitConfiguration {
..Default::default()
},
selection_configuration: SelectionConfiguration {
..Default::default()
},
crossover_configuration: CrossoverConfiguration {
..Default::default()
},
mutation_configuration: MutationConfiguration {
..Default::default()
},
save_progress_configuration: SaveProgressConfiguration {
..Default::default()
},
elitism_count: 0,
stagnation_generations: None,
convergence_threshold: None,
max_duration_secs: None,
niching_configuration: None,
extension_configuration: None,
rng_seed: None,
crossover_portfolio: None,
mutation_portfolio: None,
aos_strategy: crate::aos::AosStrategy::pm_default(),
aos_reward_window: 50,
local_search_configuration: None,
length_penalty: None,
}
}
}
impl GaConfiguration {
pub fn limit(&self) -> &LimitConfiguration {
&self.limit_configuration
}
pub fn selection(&self) -> &SelectionConfiguration {
&self.selection_configuration
}
pub fn crossover(&self) -> &CrossoverConfiguration {
&self.crossover_configuration
}
pub fn mutation(&self) -> &MutationConfiguration {
&self.mutation_configuration
}
pub fn survivor(&self) -> Survivor {
self.survivor
}
pub fn save_progress(&self) -> &SaveProgressConfiguration {
&self.save_progress_configuration
}
pub fn extension(&self) -> Option<&ExtensionConfiguration> {
self.extension_configuration.as_ref()
}
pub fn adaptive_ga(&self) -> bool {
self.adaptive_ga
}
pub fn number_of_threads(&self) -> usize {
self.number_of_threads
}
pub fn elitism_count(&self) -> usize {
self.elitism_count
}
pub fn stagnation_generations(&self) -> Option<usize> {
self.stagnation_generations
}
pub fn convergence_threshold(&self) -> Option<f64> {
self.convergence_threshold
}
pub fn max_duration_secs(&self) -> Option<f64> {
self.max_duration_secs
}
}
mod builders;