M codes/eoa_lib/src/crossover.rs => codes/eoa_lib/src/crossover.rs +1 -1
@@ 4,7 4,7 @@ use nalgebra::{allocator::Allocator, DefaultAllocator, Dim, OVector, Scalar, U1}
use rand::{seq::IteratorRandom, Rng, RngCore};
use rand_distr::Uniform;
-use crate::{binary_string::BinaryString, pairing::ParentPairing, replacement::{EvaluatedPopulation, Population}};
+use crate::{binary_string::BinaryString, pairing::ParentPairing, population::{EvaluatedPopulation, Population}};
pub trait Crossover<const D: usize> {
type Chromosome;
M codes/eoa_lib/src/evolution.rs => codes/eoa_lib/src/evolution.rs +2 -2
@@ 1,7 1,7 @@
use std::error::Error;
use rand::RngCore;
-use crate::{comparison::BetterThanOperator, crossover::Crossover, fitness::FitnessFunction, pairing::Pairing, perturbation::PerturbationOperator, replacement::{EvaluatedChromosome, EvaluatedPopulation, Population, Replacement}, selection::Selection};
+use crate::{comparison::BetterThanOperator, crossover::Crossover, fitness::FitnessFunction, pairing::Pairing, perturbation::PerturbationOperator, population::{EvaluatedChromosome, EvaluatedPopulation, Population}, replacement::Replacement, selection::Selection};
#[derive(Clone, Debug)]
pub struct EvolutionCandidate<TInput, TResult> {
@@ 173,7 173,7 @@ pub fn evolution_algorithm
pub mod tests {
use nalgebra::Const;
- use crate::{binary_string::BinaryString, comparison::MinimizingOperator, crossover::BinaryOnePointCrossover, fitness::one_max::OneMax, initializer::{Initializer, RandomInitializer}, pairing::AdjacentPairing, perturbation::{BinaryStringBitPerturbation, BinaryStringFlipPerturbation, BinaryStringSingleBitPerturbation, CombinedPerturbation, MutationPerturbation}, replacement::{BestReplacement, Population, TournamentReplacement}, selection::TournamentSelection};
+ use crate::{binary_string::BinaryString, comparison::MinimizingOperator, crossover::BinaryOnePointCrossover, fitness::one_max::OneMax, initializer::{Initializer, RandomInitializer}, pairing::AdjacentPairing, perturbation::{BinaryStringBitPerturbation, BinaryStringFlipPerturbation, BinaryStringSingleBitPerturbation, CombinedPerturbation, MutationPerturbation}, population::Population, replacement::{BestReplacement, TournamentReplacement}, selection::TournamentSelection};
use super::evolution_algorithm;
M codes/eoa_lib/src/lib.rs => codes/eoa_lib/src/lib.rs +1 -0
@@ 1,5 1,6 @@
pub mod fitness;
pub mod pairing;
+pub mod population;
pub mod evolution;
pub mod crossover;
pub mod bounded;
M codes/eoa_lib/src/pairing.rs => codes/eoa_lib/src/pairing.rs +1 -1
@@ 2,7 2,7 @@ use std::marker::PhantomData;
use nalgebra::{Const, OVector, SVector};
-use crate::replacement::EvaluatedPopulation;
+use crate::population::EvaluatedPopulation;
pub type ParentPairing<const D: usize> = OVector<usize, Const<D>>;
A codes/eoa_lib/src/population.rs => codes/eoa_lib/src/population.rs +138 -0
@@ 0,0 1,138 @@
+use crate::{comparison::BetterThanOperator, fitness::FitnessFunction};
+
+#[derive(Clone, Debug)]
+pub struct Population<TChromosome> {
+ population: Vec<TChromosome>
+}
+
+#[derive(Clone, Debug)]
+pub struct EvaluatedChromosome<TChromosome, TResult> {
+ pub chromosome: TChromosome,
+ pub evaluation: TResult,
+}
+
+#[derive(Clone, Debug)]
+pub struct EvaluatedPopulation<TChromosome, TResult> {
+ pub population: Vec<EvaluatedChromosome<TChromosome, TResult>>
+}
+
+impl<TChromosome> Population<TChromosome> {
+ pub fn from_vec(vec: Vec<TChromosome>) -> Self {
+ Self {
+ population: vec
+ }
+ }
+
+ pub fn from_iterator(iter: impl Iterator<Item = TChromosome>) -> Self {
+ Self::from_vec(iter.collect())
+ }
+
+ pub fn evaluate<T: FitnessFunction<In = TChromosome>>(self, func: &T) -> Result<EvaluatedPopulation<TChromosome, T::Out>, T::Err> {
+ EvaluatedPopulation::evaluate(
+ self.population,
+ func
+ )
+ }
+
+ pub fn evaluate_mut<TResult>(self, func: &mut dyn FnMut(&TChromosome) -> TResult) -> EvaluatedPopulation<TChromosome, TResult> {
+ EvaluatedPopulation::evaluate_mut(
+ self.population,
+ func
+ )
+ }
+
+ pub fn into_iter(self) -> impl Iterator<Item = TChromosome> {
+ self.population.into_iter()
+ }
+
+ pub fn iter(&self) -> impl Iterator<Item = &TChromosome> {
+ self.population.iter()
+ }
+
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TChromosome> {
+ self.population.iter_mut()
+ }
+}
+
+impl<TInput, TResult> EvaluatedChromosome<TInput, TResult> {
+ pub fn deconstruct(self) -> (TInput, TResult) {
+ (self.chromosome, self.evaluation)
+ }
+}
+
+impl<TChromosome, TResult> EvaluatedPopulation<TChromosome, TResult> {
+ pub fn new() -> Self {
+ Self {
+ population: vec![]
+ }
+ }
+
+ pub fn evaluate<T: FitnessFunction<In = TChromosome, Out = TResult>>(chromosomes: Vec<TChromosome>, func: &T) -> Result<Self, T::Err> {
+ Ok(EvaluatedPopulation::from_vec(
+ chromosomes.into_iter()
+ .map(|chromosome|
+ Ok(EvaluatedChromosome {
+ evaluation: func.fit(&chromosome)?,
+ chromosome
+ }))
+ .collect::<Result<_, _>>()?))
+ }
+
+ pub fn evaluate_mut(chromosomes: Vec<TChromosome>, func: &mut dyn FnMut(&TChromosome) -> TResult) -> Self {
+ EvaluatedPopulation::from_vec(
+ chromosomes.into_iter()
+ .map(|chromosome|
+ EvaluatedChromosome {
+ evaluation: func(&chromosome),
+ chromosome
+ })
+ .collect::<Vec<_>>())
+ }
+
+ pub fn from_vec(vec: Vec<EvaluatedChromosome<TChromosome, TResult>>) -> Self {
+ Self {
+ population: vec
+ }
+ }
+
+ pub fn best_candidate(&self, better_than: &impl BetterThanOperator<TResult>) -> &EvaluatedChromosome<TChromosome, TResult> {
+ let mut best_so_far = &self.population[0];
+ for individual in self.population.iter().skip(1) {
+ if better_than.better_than(&individual.evaluation, &best_so_far.evaluation) {
+ best_so_far = individual;
+ }
+ }
+
+ best_so_far
+ }
+
+ pub fn add(&mut self, c: EvaluatedChromosome<TChromosome, TResult>) {
+ self.population.push(c)
+ }
+
+ pub fn deconstruct(self) -> Vec<EvaluatedChromosome<TChromosome, TResult>> {
+ self.population
+ }
+
+ pub fn join(&mut self, mut offsprings: EvaluatedPopulation<TChromosome, TResult>) {
+ self.population.append(&mut offsprings.population);
+ }
+
+ pub fn iter(&self) -> impl Iterator<Item = &EvaluatedChromosome<TChromosome, TResult>> {
+ self.population.iter()
+ }
+
+ pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut EvaluatedChromosome<TChromosome, TResult>> {
+ self.population.iter_mut()
+ }
+
+}
+
+impl<TChromosome, TResult: Copy> EvaluatedPopulation<TChromosome, TResult> {
+ pub fn evaluations_vec(&self) -> Vec<TResult> {
+ self.population
+ .iter()
+ .map(|individual| individual.evaluation)
+ .collect()
+ }
+}
M codes/eoa_lib/src/replacement.rs => codes/eoa_lib/src/replacement.rs +1 -138
@@ 1,7 1,7 @@
use rand::{seq::IteratorRandom, RngCore};
use std::fmt::Debug;
-use crate::{comparison::BetterThanOperator, fitness::FitnessFunction, selection::{Selection, TournamentSelection}};
+use crate::{comparison::BetterThanOperator, fitness::FitnessFunction, population::{EvaluatedPopulation, EvaluatedChromosome}, selection::{Selection, TournamentSelection}};
fn extract_by_indices<T>(mut x: Vec<T>, mut idxs: Vec<usize>) -> Vec<T> {
idxs.sort_unstable_by(|a, b| b.cmp(a));
@@ 17,143 17,6 @@ fn extract_by_indices<T>(mut x: Vec<T>, mut idxs: Vec<usize>) -> Vec<T> {
result
}
-#[derive(Clone, Debug)]
-pub struct Population<TChromosome> {
- population: Vec<TChromosome>
-}
-
-#[derive(Clone, Debug)]
-pub struct EvaluatedChromosome<TChromosome, TResult> {
- pub chromosome: TChromosome,
- pub evaluation: TResult,
-}
-
-#[derive(Clone, Debug)]
-pub struct EvaluatedPopulation<TChromosome, TResult> {
- pub population: Vec<EvaluatedChromosome<TChromosome, TResult>>
-}
-
-impl<TChromosome> Population<TChromosome> {
- pub fn from_vec(vec: Vec<TChromosome>) -> Self {
- Self {
- population: vec
- }
- }
-
- pub fn from_iterator(iter: impl Iterator<Item = TChromosome>) -> Self {
- Self::from_vec(iter.collect())
- }
-
- pub fn evaluate<T: FitnessFunction<In = TChromosome>>(self, func: &T) -> Result<EvaluatedPopulation<TChromosome, T::Out>, T::Err> {
- EvaluatedPopulation::evaluate(
- self.population,
- func
- )
- }
-
- pub fn evaluate_mut<TResult>(self, func: &mut dyn FnMut(&TChromosome) -> TResult) -> EvaluatedPopulation<TChromosome, TResult> {
- EvaluatedPopulation::evaluate_mut(
- self.population,
- func
- )
- }
-
- pub fn into_iter(self) -> impl Iterator<Item = TChromosome> {
- self.population.into_iter()
- }
-
- pub fn iter(&self) -> impl Iterator<Item = &TChromosome> {
- self.population.iter()
- }
-
- pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut TChromosome> {
- self.population.iter_mut()
- }
-}
-
-impl<TInput, TResult> EvaluatedChromosome<TInput, TResult> {
- pub fn deconstruct(self) -> (TInput, TResult) {
- (self.chromosome, self.evaluation)
- }
-}
-
-impl<TChromosome, TResult> EvaluatedPopulation<TChromosome, TResult> {
- pub fn new() -> Self {
- Self {
- population: vec![]
- }
- }
-
- pub fn evaluate<T: FitnessFunction<In = TChromosome, Out = TResult>>(chromosomes: Vec<TChromosome>, func: &T) -> Result<Self, T::Err> {
- Ok(EvaluatedPopulation::from_vec(
- chromosomes.into_iter()
- .map(|chromosome|
- Ok(EvaluatedChromosome {
- evaluation: func.fit(&chromosome)?,
- chromosome
- }))
- .collect::<Result<_, _>>()?))
- }
-
- pub fn evaluate_mut(chromosomes: Vec<TChromosome>, func: &mut dyn FnMut(&TChromosome) -> TResult) -> Self {
- EvaluatedPopulation::from_vec(
- chromosomes.into_iter()
- .map(|chromosome|
- EvaluatedChromosome {
- evaluation: func(&chromosome),
- chromosome
- })
- .collect::<Vec<_>>())
- }
-
- pub fn from_vec(vec: Vec<EvaluatedChromosome<TChromosome, TResult>>) -> Self {
- Self {
- population: vec
- }
- }
-
- pub fn best_candidate(&self, better_than: &impl BetterThanOperator<TResult>) -> &EvaluatedChromosome<TChromosome, TResult> {
- let mut best_so_far = &self.population[0];
- for individual in self.population.iter().skip(1) {
- if better_than.better_than(&individual.evaluation, &best_so_far.evaluation) {
- best_so_far = individual;
- }
- }
-
- best_so_far
- }
-
- pub fn add(&mut self, c: EvaluatedChromosome<TChromosome, TResult>) {
- self.population.push(c)
- }
-
- pub fn deconstruct(self) -> Vec<EvaluatedChromosome<TChromosome, TResult>> {
- self.population
- }
-
- fn join(&mut self, mut offsprings: EvaluatedPopulation<TChromosome, TResult>) {
- self.population.append(&mut offsprings.population);
- }
-
- pub fn iter(&self) -> impl Iterator<Item = &EvaluatedChromosome<TChromosome, TResult>> {
- self.population.iter()
- }
-
- pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut EvaluatedChromosome<TChromosome, TResult>> {
- self.population.iter_mut()
- }
-
-}
-
-impl<TChromosome, TResult: Copy> EvaluatedPopulation<TChromosome, TResult> {
- pub fn evaluations_vec(&self) -> Vec<TResult> {
- self.population
- .iter()
- .map(|individual| individual.evaluation)
- .collect()
- }
-}
-
pub trait Replacement<TChromosome, TResult> {
fn replace(
&self,
M codes/eoa_lib/src/selection.rs => codes/eoa_lib/src/selection.rs +1 -1
@@ 3,7 3,7 @@ use rand::{seq::IteratorRandom, Rng, RngCore};
use rand_distr::uniform::{SampleRange, SampleUniform};
use std::{cmp::Ordering, fmt::Debug, ops::{AddAssign, Sub}};
-use crate::{comparison::BetterThanOperator, replacement::EvaluatedPopulation};
+use crate::{comparison::BetterThanOperator, population::EvaluatedPopulation};
pub trait Selection<TChromosome, TResult> {
fn select(&self,
M codes/tsp_hw01/src/crossovers.rs => codes/tsp_hw01/src/crossovers.rs +7 -7
@@ 1,7 1,7 @@
use std::marker::PhantomData;
use nalgebra::{allocator::Allocator, Const, DefaultAllocator, Dim, OMatrix, OVector, U1};
use rand::{prelude::IteratorRandom, Rng, RngCore};
-use eoa_lib::replacement::Population;
+use eoa_lib::population::Population;
use itertools::Itertools;
use eoa_lib::crossover::Crossover;
use crate::tsp::NodePermutation;
@@ 26,7 26,7 @@ where
fn crossover(
&self,
- parents: &eoa_lib::replacement::EvaluatedPopulation<Self::Chromosome, Self::Out>,
+ parents: &eoa_lib::population::EvaluatedPopulation<Self::Chromosome, Self::Out>,
pairs: impl Iterator<Item = eoa_lib::pairing::ParentPairing<2>>,
_: &mut dyn RngCore
) -> Population<Self::Chromosome> {
@@ 62,10 62,10 @@ where
fn crossover(
&self,
- parents: &eoa_lib::replacement::EvaluatedPopulation<Self::Chromosome, Self::Out>,
+ parents: &eoa_lib::population::EvaluatedPopulation<Self::Chromosome, Self::Out>,
pairs: impl Iterator<Item = eoa_lib::pairing::ParentPairing<2>>,
rng: &mut dyn RngCore
- ) -> eoa_lib::replacement::Population<Self::Chromosome> {
+ ) -> eoa_lib::population::Population<Self::Chromosome> {
let mut offsprings = vec![];
let permutation = &parents.population[0].chromosome.permutation;
@@ 225,7 225,7 @@ where
fn crossover(
&self,
- parents: &eoa_lib::replacement::EvaluatedPopulation<Self::Chromosome, Self::Out>,
+ parents: &eoa_lib::population::EvaluatedPopulation<Self::Chromosome, Self::Out>,
pairs: impl Iterator<Item = eoa_lib::pairing::ParentPairing<2>>,
rng: &mut dyn RngCore
) -> Population<Self::Chromosome> {
@@ 309,7 309,7 @@ where
fn crossover(
&self,
- parents: &eoa_lib::replacement::EvaluatedPopulation<Self::Chromosome, Self::Out>,
+ parents: &eoa_lib::population::EvaluatedPopulation<Self::Chromosome, Self::Out>,
pairs: impl Iterator<Item = eoa_lib::pairing::ParentPairing<2>>,
rng: &mut dyn RngCore
) -> Population<Self::Chromosome> {
@@ 343,7 343,7 @@ mod tests {
use std::convert::Infallible;
use nalgebra::{SVector, U6};
use rand::{rngs::StdRng, RngCore, SeedableRng};
- use eoa_lib::{fitness::FitnessFunction, initializer::Initializer, pairing::{AdjacentPairing, Pairing}, replacement::Population};
+ use eoa_lib::{fitness::FitnessFunction, initializer::Initializer, pairing::{AdjacentPairing, Pairing}, population::Population};
use crate::initializers::TSPRandomInitializer;
use crate::tsp::{NodePermutation, TSPInstance};
M codes/tsp_hw01/src/main.rs => codes/tsp_hw01/src/main.rs +7 -7
@@ 262,7 262,7 @@ fn run_evolution_algorithm(instance: &TSPInstance<Dyn>) -> Result<PlotData, Box<
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 328,7 328,7 @@ fn run_evolution_algorithm_mst(instance: &TSPInstance<Dyn>) -> Result<PlotData,
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 394,7 394,7 @@ fn run_evolution_algorithm_nn(instance: &TSPInstance<Dyn>) -> Result<PlotData, B
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 460,7 460,7 @@ fn run_evolution_algorithm_cx(instance: &TSPInstance<Dyn>) -> Result<PlotData, B
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 518,7 518,7 @@ fn run_evolution_algorithm_pmx(instance: &TSPInstance<Dyn>) -> Result<PlotData,
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 576,7 576,7 @@ fn run_evolution_algorithm_erx(instance: &TSPInstance<Dyn>) -> Result<PlotData,
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
// Run evolution algorithm
let parents_count = EA_PARENTS_COUNT;
@@ 636,7 636,7 @@ fn run_evolution_algorithm_binary(instance: &TSPInstance<Dyn>) -> Result<PlotDat
// Create initial population
let population_size = EA_POPULATION_SIZE;
let initial_population = initializer.initialize(input_dimension, population_size, &mut rng);
- let initial_population = eoa_lib::replacement::Population::from_vec(initial_population);
+ let initial_population = eoa_lib::population::Population::from_vec(initial_population);
let fitness = TSPBinaryStringWrapper::new(instance, input_dimension, output_dimension).unwrap();