From d4a1467689b3e87041c6b9fa57191c5a2aaf1506 Mon Sep 17 00:00:00 2001 From: Helena Stegherr Date: Mon, 4 Dec 2023 11:02:46 +0100 Subject: [PATCH] Improve according to review comments --- src/components/replacement/bh.rs | 32 +++++++++++++++----------------- src/components/swarm/bh.rs | 12 ++++++------ src/utils.rs | 2 +- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/components/replacement/bh.rs b/src/components/replacement/bh.rs index 2eb4490..a716e1a 100644 --- a/src/components/replacement/bh.rs +++ b/src/components/replacement/bh.rs @@ -4,8 +4,8 @@ use rand::Rng; use serde::{Deserialize, Serialize}; use crate::{ - population::BestIndividual, problems::LimitedVectorProblem, utils::squared_euclidean, - Component, ExecResult, Individual, SingleObjectiveProblem, State, + problems::LimitedVectorProblem, utils::squared_euclidean, + Component, ExecResult, SingleObjectiveProblem, State, }; #[derive(Clone, Serialize, Deserialize)] @@ -28,35 +28,33 @@ where { fn execute(&self, problem: &P, state: &mut State

) -> ExecResult<()> { let mut populations = state.populations_mut(); - let offspring = populations.pop(); + let mut offspring = populations.pop(); let f_bh = state.best_objective_value().unwrap().value(); let fitness_sum = offspring.iter().map(|x| x.objective().value()).sum::(); let radius = f_bh / fitness_sum; - let best_ind = offspring.best_individual().cloned(); - let best = best_ind.unwrap().solution().clone(); + let (index, best) = offspring + .iter() + .enumerate() + .min_by_key(|(_u, i)| i.objective()) + .unwrap(); let distances = offspring .iter() - .map(|o| squared_euclidean(o.solution(), &best).sqrt()) + .map(|o| squared_euclidean(o.solution(), best.solution()).sqrt()) .collect::>(); - let mut new_offspring: Vec> = vec![]; - for (u, i) in offspring.iter().enumerate() { + for (u, i) in offspring.iter_mut().enumerate() { // do not replace best individual - if distances[u] < radius && distances[u] != 0.0 { - let rand: Vec = (0..problem.dimension()) - .map(|_| state.random_mut().gen_range(problem.domain()[0].clone())) + if distances[u] < radius && u != index { + let rand: Vec = problem.domain().iter() + .map(|d| state.random_mut().gen_range(d.clone())) .collect(); - let j = Individual::new_unevaluated(rand); - //println!("{:?}, {:?}", u, &j); - new_offspring.push(j); - } else { - new_offspring.push(i.clone()); + *i.solution_mut() = rand; } } - populations.push(new_offspring); + populations.push(offspring); Ok(()) } } diff --git a/src/components/swarm/bh.rs b/src/components/swarm/bh.rs index efdb8ec..a4ecd45 100644 --- a/src/components/swarm/bh.rs +++ b/src/components/swarm/bh.rs @@ -62,20 +62,20 @@ where } fn execute(&self, _problem: &P, state: &mut State

) -> ExecResult<()> { - let distr = Uniform::new(0.0, 1.0); + let distribution = Uniform::new(0.0, 1.0); // Get necessary state like global best `xg` let best = state.populations().current().best_individual().cloned(); - let binding = best.unwrap(); - let xg = binding.solution(); - let mut binding2 = state.populations_mut(); - let xs = binding2.current_mut().as_solutions_mut(); + let best_ind = best.unwrap(); + let xg = best_ind.solution(); + let mut population = state.populations_mut(); + let xs = population.current_mut().as_solutions_mut(); // Perform the update step. for x in xs { for i in 0..x.len() { // Calculate change in position - let pos = distr.sample(&mut *state.random_mut()) * (xg[i] - x[i]); + let pos = distribution.sample(&mut *state.random_mut()) * (xg[i] - x[i]); // Add value to particle position x[i] += pos; } diff --git a/src/utils.rs b/src/utils.rs index ebf09a7..d5a2c7f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -47,5 +47,5 @@ impl serde::Serialize for SerializablePhantom { /// Calculates squared Euclidean distance between two vectors. pub fn squared_euclidean(a: &[f64], b: &Vec) -> f64 { - a.iter().zip(b).map(|(p, q)| (p - q).powf(2.0)).sum::() + a.iter().zip(b).map(|(p, q)| (p - q).powi(2)).sum::() }