5 releases
0.2.0 | Jul 6, 2020 |
---|---|
0.1.3 | Jul 4, 2020 |
0.1.2 | Jul 3, 2020 |
0.1.1 | Jul 2, 2020 |
0.1.0 | Jun 30, 2020 |
#1518 in Algorithms
65KB
1.5K
SLoC
PSO
Easy and Efficient Particle Swarm Optimizer in Rust
Features
- Efficient Multi-Threaded optimization
- Simple API with many optional parameters to configure
- Minimizes an N dimensional objective function defined as a closure
- Lots of fanciness under the hood to avoid local minima traps
Examples
Simple
// set up a PSO with 8 default swarms
let pso = PSO::default(8, false);
// set up the stop condition and search space with a JobConfig
let mut jc = JobConfig::new(5); // search a 5 variable space
jc.exit_cost(10e-10); // stop optimizing when the objective cost reaches 10e-10
jc.variable_bound([-5.0, 5.0]); // constrain the 5D search space to (-5, 5) along all dimensions
// create a simple objective function
let obj = |x_vec: &[f64]| -> f64 { x_vec.iter().map(|x| x.powi(2)).sum::<f64>() };
// search for the minimum
let min = pso.run_job_fn(jc, obj);
assert!(min.0 < 10e-9);
for x in min.1 {
assert!(x.abs() < 0.001);
}
Advanced
// define a swarm configuration
let mut sc = SwarmConfig::new();
sc.synergic_behavior(0.4, 100); // collaborate with other swarms every 100 iterations using a global-coefficient of 0.4
sc.motion_coefficients(0.5, 0.6, 1.0); // use custom motion coefficients
sc.num_particles(256); // put 256 particles in each swarm
// set up a PSO with 8 swarms using the above SwarmConfig
let pso = PSO::from_swarm_config(8, false, &sc);
// set up the stop condition and search space with a JobConfig
let mut jc = JobConfig::new(5);
jc.max_iter_and_exit_cost(10000, 10e-10); // stop after the first of these conditions is met
jc.variable_bounds(vec![
// define a custom upper and lower bound on each dimension
[-10.0, 10.0],
[-8.0, 8.0],
[-6.0, 6.0],
[-4.0, 4.0],
[-2.0, 2.0],
]);
jc.update_console(100); // update the console with the current minimum every 100 iterations
// create a simple objective function using some external data
let mins = [1.0; 5];
let obj = move |x_vec: &[f64]| -> f64 {
x_vec
.iter()
.enumerate()
.map(|(i, x)| (x - mins[i]).powi(2))
.sum::<f64>()
};
// search for the minimum
let min = pso.run_job_fn(jc, obj);
assert!(min.0 < 10e-9);
for (i, x) in min.1.iter().enumerate() {
assert!((x - mins[i]).abs() < 0.001);
}
Dependencies
~3–4MB
~74K SLoC