use fastrand::Rng;
use ganesh::{
algorithms::particles::{
pso::PSOConfig, Swarm, SwarmPositionInitializer, TrackingSwarmObserver, PSO,
},
core::{Callbacks, MaxSteps},
traits::{Algorithm, CostFunction},
DVector, Float, PI,
};
use std::{convert::Infallible, error::Error, fs::File, io::BufWriter, path::Path};
fn main() -> Result<(), Box<dyn Error>> {
struct Problem;
impl CostFunction for Problem {
fn evaluate(&self, x: &DVector<Float>, _args: &()) -> Result<Float, Infallible> {
Ok(10.0
+ (x[0].powi(2) - 10.0 * Float::cos(2.0 * PI * x[0]))
+ (x[1].powi(2) - 10.0 * Float::cos(2.0 * PI * x[1])))
}
}
let problem = Problem;
let mut rng = Rng::new();
rng.seed(0);
let tracker = TrackingSwarmObserver::new();
let mut pso = PSO::default();
let init = Swarm::new(SwarmPositionInitializer::RandomInLimits {
bounds: vec![(-20.0, 20.0), (-20.0, 20.0)],
n_particles: 50,
});
let config = PSOConfig::default()
.with_c1(0.1)?
.with_c2(0.1)?
.with_omega(0.8)?;
let result = pso.process(
&problem,
&(),
init,
config,
Callbacks::empty()
.with_observer(tracker.clone())
.with_terminator(MaxSteps(200)),
)?;
println!("{}", result);
let mut writer = BufWriter::new(File::create(Path::new("data.pkl"))?);
serde_pickle::to_writer(&mut writer, &tracker, Default::default())?;
Ok(())
}