use crate::fitness::{allow_objective_func, FitnessEvaluator, Rastrigin};
use crate::params::{CmaesParams, CmaesParamsValidator};
use crate::state::{CmaesState, CmaesStateLogic};
use crate::strategy::{CmaesAlgo, CmaesAlgoOptimizer};
use anyhow::Result;
use nalgebra::DVector;
use std::io::{self, Write};
use std::time::Instant;
pub fn example() -> Result<()> {
let verbose = true;
let start = Instant::now();
let objective_function = Rastrigin { obj_dim: 50 };
let (obj, obj_dim) = allow_objective_func(objective_function)?;
let params = CmaesParams::new()?
.set_popsize(50)?
.set_xstart(vec![0.0; obj_dim])?
.set_sigma(0.25)?;
let cmaes = CmaesAlgo::new(params)?;
let mut state = CmaesState::init_state(&cmaes.params)?;
let (mut step, mut best_y) = (0, vec![99.]);
loop {
let mut pop = cmaes.ask(&mut state)?;
let mut fitness = obj.evaluate(&pop)?;
state = cmaes.tell(state, &mut pop, &mut fitness)?;
best_y.push(state.best_y_fit.row(0)[0]);
let last_50_best_y = if best_y.len() > 25 {
best_y[best_y.len() - 25..].to_vec()
} else {
best_y[..].to_vec()
};
let best_y_avg = DVector::from_vec(last_50_best_y).mean();
if verbose {
print!("{:+.4?} ", &best_y_avg);
io::stdout().flush().unwrap()
}
if (state.best_y_fit.row(0)[0] - best_y_avg).abs() < cmaes.params.tol {
if verbose {
println!(" ===> Search stopped due to tolerance change met")
}
break;
}
step += 1;
}
if verbose {
println!(
"Step {} | Fitness: {:+.4?} | Duration p/step: {:.4} secs",
step,
&state.best_y_fit.row(0)[0],
(start.elapsed().as_micros() as f32) / 1000000.0 / (step as f32)
)
}
Ok(())
}