-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework pso #112
Rework pso #112
Changes from 3 commits
8c037eb
f0f83bc
60f5708
3d176e7
5437f5b
1147f76
f266a51
134232b
985dd04
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
//! Archiving methods | ||
|
||
use crate::operators::state::custom_state::ElitistArchiveState; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same thing as here with the imports. |
||
use crate::{ | ||
framework::{components::*, state::State}, | ||
operators::custom_state::ElitistArchiveState, | ||
problems::SingleObjectiveProblem, | ||
}; | ||
use serde::{Deserialize, Serialize}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
//! Swarm Operators | ||
|
||
use crate::operators::state::custom_state::PsoState; | ||
use rand::distributions::Uniform; | ||
use rand::Rng; | ||
|
||
use crate::{ | ||
framework::{components::*, state::State, Individual, Random}, | ||
problems::SingleObjectiveProblem, | ||
}; | ||
|
||
/// Applies the PSO specific generation operator. | ||
/// | ||
/// Requires [PsoStateUpdate][crate::heuristics::pso::pso_ops::PsoStateUpdate]. | ||
#[derive(serde::Serialize)] | ||
pub struct PsoGeneration { | ||
/// Inertia weight for influence of old velocity | ||
pub weight: f64, | ||
/// First constant factor for influence of previous best (also called Acceleration coefficient 1) | ||
pub c_one: f64, | ||
/// Second constant factor for influence of global best (also called Acceleration coefficient 2) | ||
pub c_two: f64, | ||
/// Maximum velocity | ||
pub v_max: f64, | ||
} | ||
impl PsoGeneration { | ||
pub fn new<P>(weight: f64, c_one: f64, c_two: f64, v_max: f64) -> Box<dyn Component<P>> | ||
where | ||
P: SingleObjectiveProblem<Encoding = Vec<f64>>, | ||
{ | ||
Box::new(Self { | ||
weight, | ||
c_one, | ||
c_two, | ||
v_max, | ||
}) | ||
} | ||
} | ||
impl<P> Component<P> for PsoGeneration | ||
where | ||
P: SingleObjectiveProblem<Encoding = Vec<f64>>, | ||
{ | ||
fn initialize(&self, _problem: &P, state: &mut State) { | ||
state.require::<PsoState<P>>(); | ||
} | ||
|
||
fn execute(&self, _problem: &P, state: &mut State) { | ||
let &Self { | ||
weight, | ||
c_one, | ||
c_two, | ||
v_max, | ||
} = self; | ||
|
||
let mut offspring = Vec::new(); | ||
let mut parents = state.population_stack_mut::<P>().pop(); | ||
|
||
let rng = state.random_mut(); | ||
let rng_iter = |rng: &mut Random| { | ||
rng.sample_iter(Uniform::new(0., 1.)) | ||
.take(parents.len()) | ||
.collect::<Vec<_>>() | ||
}; | ||
|
||
// it might be debatable if one should use a vector of different random numbers or of the same | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we could just add a parameter for it. We could even add properly named alternatives to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather leave it as is, because it's in my opinion unnecessary to differentiate. I just wanted to leave the comment as a reminder if we want to explain it somewhere. |
||
// both versions exist in the literature | ||
let r_one = rng_iter(rng); | ||
let r_two = rng_iter(rng); | ||
|
||
let pso_state = state.get_mut::<PsoState<P>>(); | ||
|
||
for (i, x) in parents.drain(..).enumerate() { | ||
let mut x = x.into_solution(); | ||
let v = &mut pso_state.velocities[i]; | ||
let xp = pso_state.bests[i].solution(); | ||
let xg = pso_state.global_best.solution(); | ||
|
||
for i in 0..v.len() { | ||
v[i] = weight * v[i] | ||
+ c_one * r_one[i] * (xp[i] - x[i]) | ||
+ c_two * r_two[i] * (xg[i] - x[i]); | ||
v[i] = v[i].clamp(-v_max, v_max); | ||
} | ||
|
||
for i in 0..x.len() { | ||
//TODO we will need constraint handling here | ||
x[i] = (x[i] + v[i]).clamp(-1.0, 1.0); | ||
} | ||
|
||
offspring.push(Individual::<P>::new_unevaluated(x)); | ||
} | ||
|
||
state.population_stack_mut().push(offspring); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was it intended to shuffle the imports around here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was probably
cargo fmt
, which gave me lots of suggestions to shuffle imports.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, because these are the only changes in this file, and
cargo fmt
didn't complain before (or else the CI would fail).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know, but somehow it did complain a lot. I don't know what's the issue here.