diff --git a/src/learner.rs b/src/learner.rs index c955bbc..67754c7 100644 --- a/src/learner.rs +++ b/src/learner.rs @@ -31,40 +31,25 @@ impl Learner { } pub fn calculate_formula(&mut self) -> Formula { for _ in 0..self.iterations { - let current_best = Learner::get_similarity( - &self.expected_outputs, - &self.best_algorithm.run(self.inputs.clone()), - ); - let found_best = self.iterate(); - if found_best.1 > current_best.unwrap_or(0.) { - self.best_algorithm = found_best.0; - } + self.best_algorithm = self.iterate() } self.best_algorithm.clone() } - pub fn calculate_formula_debug(&mut self, tree: bool, sim: bool) -> Formula { + pub fn calculate_formula_debug(&mut self) -> Formula { for _ in 0..self.iterations { - let current_best = Learner::get_similarity( - &self.expected_outputs, - &self.best_algorithm.run(self.inputs.clone()), - ); - let found_best = self.iterate(); - - if sim { - println!("{:?}", &found_best.1); - } - if tree { - self.best_algorithm.display_tree(); - } - - if found_best.1 > current_best.unwrap_or(0.) { - self.best_algorithm = found_best.0; - } + self.best_algorithm = self.iterate(); + self.best_algorithm.display_tree(); } self.best_algorithm.clone() } - fn iterate(&self) -> (Formula, f64) { - let mut formulas: Vec<(Formula, f64)> = vec![]; + fn iterate(&self) -> Formula { + let best_similarity = Learner::get_similarity( + &self.expected_outputs, + &self.best_algorithm.run(self.inputs.clone()), + ) + .unwrap(); + let mut formulas: Vec<(Formula, f64)> = + vec![(self.best_algorithm.clone(), best_similarity)]; for _ in 0..self.formulas_per_iteration { let mut formula = self.best_algorithm.clone(); Learner::mutate_formula_randomly(&mut formula); @@ -86,23 +71,20 @@ impl Learner { } }) .unwrap() + .0 .clone() } fn mutate_formula_randomly(formula: &mut Formula) { - let amount_of_mutations = random_range(1..4); - for _ in 0..amount_of_mutations { - let mut editor = formula.modify_random_node(); - let decided_action = random_range(0..4); - - if decided_action == ACTION_ADD { - editor.add_node(editor.get_random_node()); - } else if decided_action == ACTION_REMOVE { - editor.remove_node(None); - } else if decided_action == ACTION_INSERT { - editor.insert_node(editor.get_random_node(), None); - } else if decided_action == ACTION_MUTATE { - editor.mutate_node(); - } + let mut editor = formula.modify_random_node(); + let decided_action = random_range(0..4); + if decided_action == ACTION_ADD { + editor.add_node(editor.get_random_node()); + } else if decided_action == ACTION_REMOVE { + editor.remove_node(None); + } else if decided_action == ACTION_INSERT { + editor.insert_node(editor.get_random_node(), None); + } else if decided_action == ACTION_MUTATE { + editor.mutate_node(); } } pub fn get_similarity(expected_output: &Vec, real_output: &Vec) -> Result { diff --git a/src/main.rs b/src/main.rs index e036bff..227458a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,11 +9,11 @@ mod tests; fn main() { let mut learner = Learner::new( vec![0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.], - vec![0., 1., 4., 9., 16., 25., 36., 49., 64., 81., 100.], - None, + vec![0., 2., 4., 6., 8., 10., 12., 14., 16., 19., 20.], None, + Some(10000), ); - let formula = learner.calculate_formula(); + let formula = learner.calculate_formula_debug(); println!("{:?}", formula.as_text()); formula.display_tree(); } diff --git a/src/node/mod.rs b/src/node/mod.rs index 80df59a..7763d21 100644 --- a/src/node/mod.rs +++ b/src/node/mod.rs @@ -88,7 +88,7 @@ impl Node { } => { self.max_children_count = max_args.clone(); if let Some(x) = max_args { - self.children.resize(x.clone(), Node::number(0.)); + self.children.truncate(x.clone()); } } NodeHandler::Variable => { diff --git a/src/node/node_modifier/mod.rs b/src/node/node_modifier/mod.rs index 596ed1d..dba5d2f 100644 --- a/src/node/node_modifier/mod.rs +++ b/src/node/node_modifier/mod.rs @@ -146,7 +146,17 @@ impl<'a> NodeModifier<'a> { mut node: Node, between: Option, ) -> Result<(), NodeManipulationError> { + if let Some(x) = self.picked_node.max_children_count { + if self.picked_node.children.len() + 1 > x { + return Err(NodeManipulationError::TooMuchChildren(node)); + } + } let children_count = self.picked_node.children.len(); + if let NodeHandler::Empty = &self.picked_node.handler + && children_count - 1 > 0 + { + return Err(NodeManipulationError::TooMuchChildren(node)); + } if children_count <= 0 { return Err(NodeManipulationError::NotEnoughChildren); } diff --git a/src/tests.rs b/src/tests.rs index d195ed8..82ca988 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -22,8 +22,8 @@ fn test_plus_one() { ), None ) - .inspect_err(|x| println!("{x}")) - .is_ok() + .is_err() + == false ); let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]); assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64]) @@ -39,15 +39,16 @@ fn test_branch_sum() { Node::function("Sum".to_string(), |inputs| inputs.iter().sum(), Some(2), 0), None ) - .inspect_err(|x| println!("{x}")) - .is_ok() + .is_err() + == false ); assert!( formula .modify_tree() .go_down(0) .add_node(Node::number(1f64)) - .is_ok() + .is_err() + == false ); let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]); assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64]) @@ -63,8 +64,8 @@ fn test_display_as_text() { Node::function("sum".to_string(), |inputs| inputs.iter().sum(), None, 0), None ) - .inspect_err(|x| println!("{x}")) - .is_ok() + .is_err() + == false ); assert!( formula @@ -76,8 +77,8 @@ fn test_display_as_text() { Some(1), 0 )) - .inspect_err(|x| println!("{x}")) - .is_ok() + .is_err() + == false ); assert!( formula @@ -85,8 +86,8 @@ fn test_display_as_text() { .go_down(0) .go_down(1) .add_node(Node::variable()) - .inspect_err(|x| println!("{x}")) - .is_ok() + .is_err() + == false ); assert_eq!(formula.as_text(), "sum(X,sin(X))".to_string()); }