diff --git a/artificial_bee_colony/src/lib.rs b/artificial_bee_colony/src/lib.rs index b71c77b..164bbb5 100644 --- a/artificial_bee_colony/src/lib.rs +++ b/artificial_bee_colony/src/lib.rs @@ -1,223 +1,3 @@ -use core::str; -use std::{ - env::args, - fs::{File, OpenOptions}, - io::{self, BufRead, BufReader, Write}, - process::exit, -}; - -use food::FoodSource; - pub mod bee; pub mod food; - -pub struct Input { - pub decision_variable_count: usize, - pub food_source_number: u128, - pub food_source_try_limit: u128, - pub upper_bound: f64, - pub lower_bound: f64, - pub iteration: usize, - pub run: usize, -} -impl Input { - pub fn get() -> Self { - let mut read_file = false; - for arg in args().collect::>() { - match arg.as_str() { - "-r" | "--read_file" => read_file = true, - "-h" | "--help" => { - show_help(); - exit(0); - } - _ => {} - } - } - - if read_file { - Input::read_config_file_input() - } else { - Input::user_interactive_input() - } - } - - fn user_interactive_input() -> Self { - println!("Decision Variable Count"); - let decision_variable_count = Self::get_input().parse().unwrap(); - - println!("Food Source Number"); - let food_source_number = Self::get_input().parse().unwrap(); - - println!("Food Source Try Limit"); - let food_source_try_limit = Self::get_input().parse().unwrap(); - - println!("Upper Bound"); - let upper_bound = Self::get_input().parse().unwrap(); - - println!("Lower Bound"); - let lower_bound = Self::get_input().parse().unwrap(); - - println!("Iteration"); - let iteration = Self::get_input().parse().unwrap(); - - println!("Run"); - let run = Self::get_input().parse().unwrap(); - Input { - decision_variable_count, - food_source_number, - food_source_try_limit, - upper_bound, - lower_bound, - iteration, - run, - } - } - - fn read_config_file_input() -> Input { - let mut config_file_input = Self { - decision_variable_count: 0, - food_source_number: 0, - food_source_try_limit: 0, - upper_bound: 0.0, - lower_bound: 0.0, - iteration: 0, - run: 0, - }; - - let config_file = File::open("abc_config.toml").unwrap(); - let reader = BufReader::new(config_file); - let mut words = vec![]; - for line in reader.lines().map(|x| x.unwrap()).collect::>() { - let mut parsed = line - .split('=') - .map(|x| x.trim().to_string()) - .collect::>(); - words.append(&mut parsed); - } - if words[0].as_str() == "[start_parameters]" { - for i in (1..words.len()).step_by(2) { - match words[i].as_str() { - "decision_variable_count" => { - config_file_input.decision_variable_count = words[i + 1].parse().unwrap() - } - "food_source_number" => { - config_file_input.food_source_number = words[i + 1].parse().unwrap() - } - "food_source_try_limit" => { - config_file_input.food_source_try_limit = words[i + 1].parse().unwrap() - } - "upper_bound" => config_file_input.upper_bound = words[i + 1].parse().unwrap(), - "lower_bound" => config_file_input.lower_bound = words[i + 1].parse().unwrap(), - "iteration" => config_file_input.iteration = words[i + 1].parse().unwrap(), - "run" => config_file_input.run = words[i + 1].parse().unwrap(), - _ => {} - } - } - } - config_file_input - } - - fn get_input() -> String { - let mut input = String::new(); - io::stdin().read_line(&mut input).unwrap(); - input.trim().to_string() - } -} - -pub fn give_output( - best_food_source: &FoodSource, - function_results: &[f64], - fitness_results: &[f64], - input_run: usize, - run_counter: usize, -) { - let mut write_file = false; - for arg in args().collect::>() { - match arg.as_str() { - "-w" | "--write_file" => write_file = true, - _ => {} - } - } - - let mut print_buffer = vec![]; - write!(print_buffer, "[{}]\n{}\n", run_counter, best_food_source).unwrap(); - if run_counter == input_run - 1 { - let function_results_arithmetic_mean = arithmetic_mean(function_results); - let function_results_standard_deviation = - standard_deviation(function_results, function_results_arithmetic_mean); - let fitness_results_arithmetic_mean = arithmetic_mean(fitness_results); - let fitness_results_standard_deviation = - standard_deviation(fitness_results, fitness_results_arithmetic_mean); - write!( - print_buffer, - "[function_calculations_results]\narithmetic_mean = {:e}\nstandard_deviation = {:e}\n\n[fitness_calculations_results]\narithmetic_mean = {:e}\nstandard_deviation = {:e}", - function_results_arithmetic_mean, function_results_standard_deviation, fitness_results_arithmetic_mean, fitness_results_standard_deviation - ) - .unwrap(); - } - if write_file { - write_output_file(&print_buffer[..], run_counter) - } else { - give_terminal_output(&print_buffer[..]) - } -} - -fn give_terminal_output(print_buffer: &[u8]) { - println!("{}", str::from_utf8(print_buffer).unwrap()); -} - -fn write_output_file(print_buffer: &[u8], run_counter: usize) { - let mut file_try_counter = 0; - let file_name = "abc_result"; - let file_extension = "toml"; - let mut file_path = format!("{}.{}", file_name, file_extension); - - let mut file; - if run_counter == 0 { - while File::open(file_path.clone()).is_ok() { - file_try_counter += 1; - file_path = format!("{}{}.{}", file_name, file_try_counter, file_extension); - } - file = File::create_new(file_path).unwrap(); - } else { - while File::open(file_path.clone()).is_ok() { - file_try_counter += 1; - file_path = format!("{}{}.{}", file_name, file_try_counter, file_extension); - } - if file_try_counter > 1 { - file_path = format!("{}{}.{}", file_name, file_try_counter - 1, file_extension); - } else { - file_path = format!("{}.{}", file_name, file_extension); - } - file = OpenOptions::new().append(true).open(file_path).unwrap(); - } - - file.write_all(print_buffer).unwrap(); - file.flush().unwrap(); -} - -fn arithmetic_mean(results: &[f64]) -> f64 { - let mut total_results = 0.0; - for function_result in results { - total_results += function_result - } - total_results / results.len() as f64 -} - -fn standard_deviation(results: &[f64], arithmetic_mean: f64) -> f64 { - let mut total_difference_square = 0.0; - for function_result in results { - total_difference_square += (function_result - arithmetic_mean).powi(2) - } - f64::sqrt(total_difference_square / (results.len() - 1) as f64) -} - -fn show_help() { - println!("\n\n\n"); - println!(" Arguments | Details "); - println!("----------------------------------------------------------------------"); - println!(" -r -> --read_file | Reads Config from abc_config.toml File"); - println!(" -w -> --write_file | Writes Results to abc_result.toml File"); - println!(" -h -> --help | Shows Help "); - println!("\n\n\n"); -} +pub mod utils; diff --git a/artificial_bee_colony/src/main.rs b/artificial_bee_colony/src/main.rs index f1504d1..2fae1b0 100644 --- a/artificial_bee_colony/src/main.rs +++ b/artificial_bee_colony/src/main.rs @@ -1,4 +1,8 @@ -use artificial_bee_colony::{bee::Bee, food::FoodSource, give_output, Input}; +use artificial_bee_colony::{ + bee::Bee, + food::FoodSource, + utils::{give_output, Input}, +}; fn main() { println!("Hello, world!"); @@ -61,9 +65,9 @@ fn main() { input.lower_bound, input.upper_bound, input.decision_variable_count, - ) + ); + break; } - break; } } } diff --git a/artificial_bee_colony/src/utils.rs b/artificial_bee_colony/src/utils.rs new file mode 100644 index 0000000..a3eb149 --- /dev/null +++ b/artificial_bee_colony/src/utils.rs @@ -0,0 +1,220 @@ +use core::str; +use std::{ + env::args, + fs::{File, OpenOptions}, + io::{self, BufRead, BufReader, Write}, + process::exit, +}; + +use crate::food::FoodSource; + +pub struct Input { + pub decision_variable_count: usize, + pub food_source_number: u128, + pub food_source_try_limit: u128, + pub upper_bound: f64, + pub lower_bound: f64, + pub iteration: usize, + pub run: usize, +} +impl Input { + pub fn get() -> Self { + let mut read_file = false; + for arg in args().collect::>() { + match arg.as_str() { + "-r" | "--read_file" => read_file = true, + "-h" | "--help" => { + show_help(); + exit(0); + } + _ => {} + } + } + + if read_file { + Input::read_config_file_input() + } else { + Input::user_interactive_input() + } + } + + fn user_interactive_input() -> Self { + println!("Decision Variable Count"); + let decision_variable_count = Self::get_input().parse().unwrap(); + + println!("Food Source Number"); + let food_source_number = Self::get_input().parse().unwrap(); + + println!("Food Source Try Limit"); + let food_source_try_limit = Self::get_input().parse().unwrap(); + + println!("Upper Bound"); + let upper_bound = Self::get_input().parse().unwrap(); + + println!("Lower Bound"); + let lower_bound = Self::get_input().parse().unwrap(); + + println!("Iteration"); + let iteration = Self::get_input().parse().unwrap(); + + println!("Run"); + let run = Self::get_input().parse().unwrap(); + Input { + decision_variable_count, + food_source_number, + food_source_try_limit, + upper_bound, + lower_bound, + iteration, + run, + } + } + + fn read_config_file_input() -> Input { + let mut config_file_input = Self { + decision_variable_count: 0, + food_source_number: 0, + food_source_try_limit: 0, + upper_bound: 0.0, + lower_bound: 0.0, + iteration: 0, + run: 0, + }; + + let config_file = File::open("abc_config.toml").unwrap(); + let reader = BufReader::new(config_file); + let mut words = vec![]; + for line in reader.lines().map(|x| x.unwrap()).collect::>() { + let mut parsed = line + .split('=') + .map(|x| x.trim().to_string()) + .collect::>(); + words.append(&mut parsed); + } + if words[0].as_str() == "[start_parameters]" { + for i in (1..words.len()).step_by(2) { + match words[i].as_str() { + "decision_variable_count" => { + config_file_input.decision_variable_count = words[i + 1].parse().unwrap() + } + "food_source_number" => { + config_file_input.food_source_number = words[i + 1].parse().unwrap() + } + "food_source_try_limit" => { + config_file_input.food_source_try_limit = words[i + 1].parse().unwrap() + } + "upper_bound" => config_file_input.upper_bound = words[i + 1].parse().unwrap(), + "lower_bound" => config_file_input.lower_bound = words[i + 1].parse().unwrap(), + "iteration" => config_file_input.iteration = words[i + 1].parse().unwrap(), + "run" => config_file_input.run = words[i + 1].parse().unwrap(), + _ => {} + } + } + } + config_file_input + } + + fn get_input() -> String { + let mut input = String::new(); + io::stdin().read_line(&mut input).unwrap(); + input.trim().to_string() + } +} + +pub fn give_output( + best_food_source: &FoodSource, + function_results: &[f64], + fitness_results: &[f64], + input_run: usize, + run_counter: usize, +) { + let mut write_file = false; + for arg in args().collect::>() { + match arg.as_str() { + "-w" | "--write_file" => write_file = true, + _ => {} + } + } + + let mut print_buffer = vec![]; + write!(print_buffer, "[{}]\n{}\n", run_counter, best_food_source).unwrap(); + if run_counter == input_run - 1 { + let function_results_arithmetic_mean = arithmetic_mean(function_results); + let function_results_standard_deviation = + standard_deviation(function_results, function_results_arithmetic_mean); + let fitness_results_arithmetic_mean = arithmetic_mean(fitness_results); + let fitness_results_standard_deviation = + standard_deviation(fitness_results, fitness_results_arithmetic_mean); + write!( + print_buffer, + "[function_calculations_results]\narithmetic_mean = {:e}\nstandard_deviation = {:e}\n\n[fitness_calculations_results]\narithmetic_mean = {:e}\nstandard_deviation = {:e}", + function_results_arithmetic_mean, function_results_standard_deviation, fitness_results_arithmetic_mean, fitness_results_standard_deviation + ) + .unwrap(); + } + if write_file { + write_output_file(&print_buffer[..], run_counter) + } else { + give_terminal_output(&print_buffer[..]) + } +} + +fn give_terminal_output(print_buffer: &[u8]) { + println!("{}", str::from_utf8(print_buffer).unwrap()); +} + +fn write_output_file(print_buffer: &[u8], run_counter: usize) { + let mut file_try_counter = 0; + let file_name = "abc_result"; + let file_extension = "toml"; + let mut file_path = format!("{}.{}", file_name, file_extension); + + let mut file; + if run_counter == 0 { + while File::open(file_path.clone()).is_ok() { + file_try_counter += 1; + file_path = format!("{}{}.{}", file_name, file_try_counter, file_extension); + } + file = File::create_new(file_path).unwrap(); + } else { + while File::open(file_path.clone()).is_ok() { + file_try_counter += 1; + file_path = format!("{}{}.{}", file_name, file_try_counter, file_extension); + } + if file_try_counter > 1 { + file_path = format!("{}{}.{}", file_name, file_try_counter - 1, file_extension); + } else { + file_path = format!("{}.{}", file_name, file_extension); + } + file = OpenOptions::new().append(true).open(file_path).unwrap(); + } + + file.write_all(print_buffer).unwrap(); + file.flush().unwrap(); +} + +fn arithmetic_mean(results: &[f64]) -> f64 { + let mut total_results = 0.0; + for function_result in results { + total_results += function_result + } + total_results / results.len() as f64 +} + +fn standard_deviation(results: &[f64], arithmetic_mean: f64) -> f64 { + let mut total_difference_square = 0.0; + for function_result in results { + total_difference_square += (function_result - arithmetic_mean).powi(2) + } + f64::sqrt(total_difference_square / (results.len() - 1) as f64) +} + +fn show_help() { + println!("\n\n\n"); + println!(" Arguments | Details "); + println!("----------------------------------------------------------------------"); + println!(" -r -> --read_file | Reads Config from abc_config.toml File"); + println!(" -w -> --write_file | Writes Results to abc_result.toml File"); + println!(" -h -> --help | Shows Help "); + println!("\n\n\n"); +}