From 20e931d2eab5a3f6ab90a847cebd35881aefc1e7 Mon Sep 17 00:00:00 2001 From: Rendo Date: Mon, 10 Nov 2025 08:25:57 +0500 Subject: [PATCH 1/4] tests now assert .is_ok instead of .is_err() == false --- src/tests.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/tests.rs b/src/tests.rs index 82ca988..2f5674c 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -22,8 +22,7 @@ fn test_plus_one() { ), None ) - .is_err() - == false + .is_ok() ); let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]); assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64]) @@ -39,16 +38,14 @@ fn test_branch_sum() { Node::function("Sum".to_string(), |inputs| inputs.iter().sum(), Some(2), 0), None ) - .is_err() - == false + .is_ok() ); assert!( formula .modify_tree() .go_down(0) .add_node(Node::number(1f64)) - .is_err() - == false + .is_ok() ); let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]); assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64]) @@ -64,8 +61,7 @@ fn test_display_as_text() { Node::function("sum".to_string(), |inputs| inputs.iter().sum(), None, 0), None ) - .is_err() - == false + .is_ok() ); assert!( formula @@ -77,8 +73,7 @@ fn test_display_as_text() { Some(1), 0 )) - .is_err() - == false + .is_ok() ); assert!( formula @@ -86,8 +81,7 @@ fn test_display_as_text() { .go_down(0) .go_down(1) .add_node(Node::variable()) - .is_err() - == false + .is_ok() ); assert_eq!(formula.as_text(), "sum(X,sin(X))".to_string()); } From 757e854d450ffe00c2110de3343aca939474bb4a Mon Sep 17 00:00:00 2001 From: Rendo Date: Mon, 10 Nov 2025 08:34:44 +0500 Subject: [PATCH 2/4] test error inspection --- src/tests.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tests.rs b/src/tests.rs index 2f5674c..d195ed8 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -22,6 +22,7 @@ fn test_plus_one() { ), None ) + .inspect_err(|x| println!("{x}")) .is_ok() ); let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]); @@ -38,6 +39,7 @@ fn test_branch_sum() { Node::function("Sum".to_string(), |inputs| inputs.iter().sum(), Some(2), 0), None ) + .inspect_err(|x| println!("{x}")) .is_ok() ); assert!( @@ -61,6 +63,7 @@ fn test_display_as_text() { Node::function("sum".to_string(), |inputs| inputs.iter().sum(), None, 0), None ) + .inspect_err(|x| println!("{x}")) .is_ok() ); assert!( @@ -73,6 +76,7 @@ fn test_display_as_text() { Some(1), 0 )) + .inspect_err(|x| println!("{x}")) .is_ok() ); assert!( @@ -81,6 +85,7 @@ fn test_display_as_text() { .go_down(0) .go_down(1) .add_node(Node::variable()) + .inspect_err(|x| println!("{x}")) .is_ok() ); assert_eq!(formula.as_text(), "sum(X,sin(X))".to_string()); From 4a111f9b58c933f2828fd227a5d13be3e6d6a2b4 Mon Sep 17 00:00:00 2001 From: Rendo Date: Mon, 10 Nov 2025 08:37:56 +0500 Subject: [PATCH 3/4] insert doesn't need to have children count check --- src/node/node_modifier/mod.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/node/node_modifier/mod.rs b/src/node/node_modifier/mod.rs index dba5d2f..596ed1d 100644 --- a/src/node/node_modifier/mod.rs +++ b/src/node/node_modifier/mod.rs @@ -146,17 +146,7 @@ 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); } From 1992ae133c8994d28c793d82e330a2aa7b5d449d Mon Sep 17 00:00:00 2001 From: Rendo Date: Mon, 10 Nov 2025 13:06:21 +0500 Subject: [PATCH 4/4] Finding algorithm now kinda works --- src/learner.rs | 64 +++++++++++++++++++++++++++++++------------------ src/main.rs | 6 ++--- src/node/mod.rs | 2 +- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src/learner.rs b/src/learner.rs index 67754c7..c955bbc 100644 --- a/src/learner.rs +++ b/src/learner.rs @@ -31,25 +31,40 @@ impl Learner { } pub fn calculate_formula(&mut self) -> Formula { for _ in 0..self.iterations { - self.best_algorithm = self.iterate() + 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.clone() } - pub fn calculate_formula_debug(&mut self) -> Formula { + pub fn calculate_formula_debug(&mut self, tree: bool, sim: bool) -> Formula { for _ in 0..self.iterations { - self.best_algorithm = self.iterate(); - self.best_algorithm.display_tree(); + 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.clone() } - 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)]; + fn iterate(&self) -> (Formula, f64) { + let mut formulas: Vec<(Formula, f64)> = vec![]; for _ in 0..self.formulas_per_iteration { let mut formula = self.best_algorithm.clone(); Learner::mutate_formula_randomly(&mut formula); @@ -71,20 +86,23 @@ impl Learner { } }) .unwrap() - .0 .clone() } fn mutate_formula_randomly(formula: &mut Formula) { - 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 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(); + } } } pub fn get_similarity(expected_output: &Vec, real_output: &Vec) -> Result { diff --git a/src/main.rs b/src/main.rs index 227458a..e036bff 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., 2., 4., 6., 8., 10., 12., 14., 16., 19., 20.], + vec![0., 1., 4., 9., 16., 25., 36., 49., 64., 81., 100.], + None, None, - Some(10000), ); - let formula = learner.calculate_formula_debug(); + let formula = learner.calculate_formula(); println!("{:?}", formula.as_text()); formula.display_tree(); } diff --git a/src/node/mod.rs b/src/node/mod.rs index 7763d21..80df59a 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.truncate(x.clone()); + self.children.resize(x.clone(), Node::number(0.)); } } NodeHandler::Variable => {