diff --git a/artificial_bee_colony/src/bee.rs b/artificial_bee_colony/src/bee.rs index 494705f..f110a56 100644 --- a/artificial_bee_colony/src/bee.rs +++ b/artificial_bee_colony/src/bee.rs @@ -20,25 +20,28 @@ impl Bee { let total_fitness = food_sources .iter() .map(|food_source| food_source.fitness_calculation) - .sum(); + .sum::(); let onlooker_bee_count = input.food_source_number; let mut where_to_look = 0; for _ in 0..onlooker_bee_count { - loop { + 'decide_what_dance_to_follow: loop { if where_to_look >= input.food_source_number { where_to_look = 0; } - if Bee::onlooker_bee( - food_sources, - where_to_look, - total_fitness, - input.decision_variable_count, - input.upper_bound, - input.lower_bound, - ) { - break; + + let fitness_for_index = food_sources[where_to_look].fitness_calculation; + if rand::thread_rng().gen_range(0.0..=1.0) < fitness_for_index / total_fitness { + Bee::onlooker_bee( + food_sources, + where_to_look, + input.decision_variable_count, + input.upper_bound, + input.lower_bound, + ); + break 'decide_what_dance_to_follow; } + where_to_look += 1; } } @@ -63,43 +66,28 @@ impl Bee { fn onlooker_bee( food_sources: &mut [FoodSource], food_source_index: usize, - total_fitness: f64, decision_variable_count: usize, upper_bound: f64, lower_bound: f64, - ) -> bool { - let fitness_for_index = food_sources[food_source_index].fitness_calculation; - if fitness_for_index / total_fitness > rand::thread_rng().gen_range(0.0..=1.0) { - Self::send_bee( - food_sources, - food_source_index, - decision_variable_count, - upper_bound, - lower_bound, - ); - return true; - } - false + ) { + Self::send_bee( + food_sources, + food_source_index, + decision_variable_count, + upper_bound, + lower_bound, + ); } pub fn scout_bee( food_sources: &mut [FoodSource], most_tried_food_source_index: usize, - limit: u128, lower_bound: f64, upper_bound: f64, decision_variable_count: usize, ) { - if food_sources[most_tried_food_source_index].try_counter > limit { - let mut coordinates_for_new = vec![]; - for _ in 0..decision_variable_count { - let random = lower_bound - + rand::thread_rng().gen_range(0.0..=1.0) * (upper_bound - lower_bound); - coordinates_for_new.push(random); - } - let new_food_source = FoodSource::new(coordinates_for_new); - food_sources[most_tried_food_source_index] = new_food_source; - } + let new_food_source = FoodSource::new(decision_variable_count, lower_bound, upper_bound); + food_sources[most_tried_food_source_index] = new_food_source; } fn send_bee( @@ -134,7 +122,7 @@ impl Bee { food_sources[food_source_index].coordinates.clone(); original_decision_variables[decision_variable_index] = candidate_decision_variable; let candidate_decision_variables = original_decision_variables; - FoodSource::new(candidate_decision_variables) + FoodSource::from_coordinates(candidate_decision_variables) }; food_sources[food_source_index].try_counter += 1; @@ -142,7 +130,6 @@ impl Bee { > food_sources[food_source_index].fitness_calculation { food_sources[food_source_index] = candidate_food_source; - food_sources[food_source_index].try_counter = 0; } } } diff --git a/artificial_bee_colony/src/food.rs b/artificial_bee_colony/src/food.rs index 05ade6b..998936d 100644 --- a/artificial_bee_colony/src/food.rs +++ b/artificial_bee_colony/src/food.rs @@ -11,7 +11,7 @@ pub struct FoodSource { } impl FoodSource { - pub fn new(coordinates: Vec) -> Self { + pub fn from_coordinates(coordinates: Vec) -> Self { let mut food_source = FoodSource { fitness_calculation: 0.0, function_calculation: 1.0, @@ -21,6 +21,16 @@ impl FoodSource { food_source.fitness_function(); food_source } + + pub fn new(decision_variable_count: usize, lower_bound: f64, upper_bound: f64) -> Self { + let mut coordinates = vec![]; + for _ in 0..decision_variable_count { + let random = rand::thread_rng().gen_range(lower_bound..=upper_bound); + coordinates.push(random); + } + FoodSource::from_coordinates(coordinates) + } + fn fitness_function(&mut self) { let calculation = Self::calculate(self.coordinates.clone()); self.function_calculation = calculation; @@ -48,12 +58,9 @@ impl FoodSource { let mut food_sources = vec![]; for _ in 0..food_source_number { - let mut coordinates = vec![]; - for _ in 0..decision_variable_count { - let random = rand::thread_rng().gen_range(lower_bound..=upper_bound); - coordinates.push(random); - } - food_sources.push(FoodSource::new(coordinates)); + let new_food_source = + FoodSource::new(decision_variable_count, lower_bound, upper_bound); + food_sources.push(new_food_source); } food_sources } diff --git a/artificial_bee_colony/src/main.rs b/artificial_bee_colony/src/main.rs index 7aea4cc..d02c424 100644 --- a/artificial_bee_colony/src/main.rs +++ b/artificial_bee_colony/src/main.rs @@ -32,14 +32,16 @@ fn main() { let most_tried_food_source_index = FoodSource::find_most_tried_food_source_index(&food_sources); - Bee::scout_bee( - &mut food_sources, - most_tried_food_source_index, - input.food_source_try_limit, - input.lower_bound, - input.upper_bound, - input.decision_variable_count, - ); + if food_sources[most_tried_food_source_index].try_counter > input.food_source_try_limit + { + Bee::scout_bee( + &mut food_sources, + most_tried_food_source_index, + input.lower_bound, + input.upper_bound, + input.decision_variable_count, + ); + } } function_results.push(best_food_source.function_calculation); fitness_results.push(best_food_source.fitness_calculation);