use crate::{Config, Environment, Population, ANN};
use crate::population::DEFAULT_FIT;
#[cfg(feature = "plot")]
use {crate::plot_values, failure::Error};
pub struct Cosyne {
config: Config,
env: Box<dyn Environment>,
pop: Population,
generation: usize,
champion_fit_history: Vec<f64>,
champion: (ANN, f64), }
impl Cosyne {
pub fn set_mutation_prob(&mut self, mp: f64) {
debug_assert!(mp >= 0.0 && mp <= 1.0);
self.pop.set_mutation_prob(mp);
}
pub fn set_mutation_strength(&mut self, ms: f64) {
debug_assert!(ms >= 0.0 && ms <= 1.0);
self.pop.set_mutation_strength(ms);
}
pub fn set_perturb_prob(&mut self, pp: f64) {
debug_assert!(pp >= 0.0 && pp <= 1.0);
self.pop.set_perturb_prob(pp);
}
pub fn new(env: Box<dyn Environment>, nn: ANN, config: Config) -> Self {
let pop = Population::new(config.clone(), &nn);
let champion = (pop.get_network(0), DEFAULT_FIT);
Self {
config,
env,
pop,
generation: 0,
champion_fit_history: vec![],
champion,
}
}
pub fn evolve(&mut self) {
let mut fits: Vec<f64> = Vec::with_capacity(self.config.pop_size);
for j in 0..self.config.pop_size {
let mut net = self.pop.get_network(j);
let fit = self.env.evaluate(&mut net);
fits.push(fit);
if fit > self.champion.1 {
self.champion = (net.clone(), fit);
}
}
self.pop.update_fitnesses(&fits);
self.pop.evolve();
self.champion_fit_history.push(self.champion().1);
info!(
"gen {}, champion fitness: {:.4}",
self.generation,
self.champion().1
);
self.generation += 1;
}
pub fn champion(&self) -> &(ANN, f64) {
&self.champion
}
#[cfg(feature = "plot")]
pub fn plot_fitness_history(
&self,
filename: &str,
resolution: (u32, u32),
) -> Result<(), Error> {
plot_values(&self.champion_fit_history, filename, resolution)
}
}