diff --git a/gemla/Cargo.toml b/gemla/Cargo.toml index 93a0e72..1223061 100644 --- a/gemla/Cargo.toml +++ b/gemla/Cargo.toml @@ -20,4 +20,5 @@ toml = "0.5.8" regex = "1" file_linked = { version = "0.1.0", path = "../file_linked" } thiserror = "1.0" -anyhow = "1.0" \ No newline at end of file +anyhow = "1.0" +rand = "0.8.4" \ No newline at end of file diff --git a/gemla/src/bin/bin.rs b/gemla/src/bin/bin.rs index cb12338..57cfe43 100644 --- a/gemla/src/bin/bin.rs +++ b/gemla/src/bin/bin.rs @@ -2,6 +2,8 @@ extern crate clap; extern crate gemla; +mod test_state; + use clap::App; use std::fs::metadata; diff --git a/gemla/src/bin/test_state/mod.rs b/gemla/src/bin/test_state/mod.rs new file mode 100644 index 0000000..4b9d994 --- /dev/null +++ b/gemla/src/bin/test_state/mod.rs @@ -0,0 +1,78 @@ +use rand::prelude::*; +use rand::rngs::ThreadRng; +use gemla::bracket::genetic_node::GeneticNode; +use gemla::error; +use std::convert::TryInto; + +const POPULATION_SIZE: u64 = 5; + +struct TestState { + pub population: Vec, + thread_rng: ThreadRng +} + +impl GeneticNode for TestState { + fn initialize() -> Result, error::Error> { + let mut thread_rng = rand::thread_rng(); + let mut population: Vec = vec![]; + + for _ in 0..POPULATION_SIZE { + population.push(thread_rng.gen::() as f64) + } + + Ok(Box::new(TestState { + population, + thread_rng + })) + } + + fn simulate(&mut self, iterations: u64) -> Result<(), error::Error> { + for _ in 0..iterations { + self.population = self.population.clone().iter().map(|p| p + self.thread_rng.gen_range(-10.0..10.0)).collect() + } + + Ok(()) + } + + fn get_fit_score(&self) -> f64 { + self.population.clone().into_iter().reduce(f64::max).unwrap() + } + + fn calculate_scores_and_trim(&mut self) -> Result<(), error::Error> { + let mut v = self.population.clone(); + + v.sort_by(|a, b| a.partial_cmp(b).unwrap()); + + self.population = v[4..].to_vec(); + + Ok(()) + } + + fn mutate(&mut self) -> Result<(), error::Error> { + loop { + if self.population.len() >= POPULATION_SIZE.try_into().unwrap() { + break; + } + + let new_individual_index = self.thread_rng.gen_range(0..self.population.len()); + let mut cross_breed_index = self.thread_rng.gen_range(0..self.population.len()); + + loop { + if new_individual_index != cross_breed_index { + break; + } + + cross_breed_index = self.thread_rng.gen_range(0..self.population.len()); + } + + let mut new_individual = self.population.clone()[new_individual_index]; + let cross_breed = self.population.clone()[cross_breed_index]; + + new_individual += cross_breed + self.thread_rng.gen_range(-10.0..10.0); + + self.population.push(new_individual); + } + + Ok(()) + } +} \ No newline at end of file