#![deny(unsafe_code)]
mod algorithms;
mod evolution;
mod individual;
mod model;
mod operators;
mod population;
mod stats;
pub use algorithms::*;
pub use evolution::*;
pub use individual::*;
pub use model::*;
pub use operators::*;
pub use population::*;
pub use stats::*;
#[inline]
pub fn interpolate_f64(min: f64, max: f64, ratio: f64) -> f64 {
min + (max - min) * ratio
}
#[inline]
pub fn interpolate_usize(min: usize, max: usize, ratio: f64) -> usize {
(min as f64 + (max - min) as f64 * ratio) as usize
}
pub mod one_max {
use super::*;
use rand::{distributions::Standard, prelude::*};
#[derive(Debug, Clone, PartialEq)]
pub struct OneMax {
genome: Vec<bool>,
fitness: f64,
}
impl OneMax {
pub fn genome(&self) -> &[bool] {
&self.genome
}
}
impl From<Vec<bool>> for OneMax {
fn from(genome: Vec<bool>) -> Self {
Self {
genome,
fitness: 0.0,
}
}
}
impl Individual for OneMax {
fn fitness(&self) -> f64 {
self.fitness
}
}
impl RandomIndividual<usize> for OneMax {
fn new_random<R: Rng>(length: &usize, rng: &mut R) -> Self {
let bits = rng.sample_iter(Standard);
let genome = Vec::from_iter(bits.take(*length));
Self::from(genome)
}
}
#[derive(Debug, Default)]
pub struct OneMaxEvolutionModel;
impl EvolutionModel for OneMaxEvolutionModel {
type Individual = OneMax;
type Rng = SmallRng;
fn rng() -> Self::Rng {
SmallRng::from_entropy()
}
fn crossover(
&self,
parent1: &Self::Individual,
parent2: &Self::Individual,
rng: &mut Self::Rng,
) -> Self::Individual {
CrossoverStrategy::SinglePoint
.crossover(&parent1.genome, &parent2.genome, rng)
.into()
}
fn mutate(&self, individual: &mut Self::Individual, rng: &mut Self::Rng) {
MutationStrategy::Duplicate.mutate(&mut individual.genome, rng);
}
fn evaluate(&self, individual: &mut Self::Individual) {
let one_bits = individual.genome.iter().filter(|&&one| one).count();
let total_bits = individual.genome.len();
individual.fitness = one_bits as f64 / total_bits as f64;
}
}
}