diff --git a/src/formula.rs b/src/formula.rs index b651fc4..f2700da 100644 --- a/src/formula.rs +++ b/src/formula.rs @@ -3,16 +3,21 @@ use crate::node::Node; #[derive(Clone)] pub struct Formula { tree: Node, - x: f64, - rating: f64, } impl Formula { - pub fn run(&mut self, inputs: Vec) -> Vec { + pub fn new() -> Self { + let mut formula = Self { + tree: Node::empty(), + }; + formula.tree.modify_tree().add_node(Node::variable()); + + formula + } + pub fn run(&self, inputs: Vec) -> Vec { let mut outputs: Vec = vec![]; for input in inputs { - self.x = input; - outputs.push(self.tree.get_value()); + outputs.push(self.tree.get_value(input)); } outputs } diff --git a/src/main.rs b/src/main.rs index e7a11a9..9e18c4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,9 @@ +use crate::formula::Formula; + +mod formula; +mod node; + fn main() { - println!("Hello, world!"); + let formula = Formula::new(); + dbg!(formula.run(vec![1f64])); } diff --git a/src/node/handler.rs b/src/node/handler.rs index 2612729..bebf744 100644 --- a/src/node/handler.rs +++ b/src/node/handler.rs @@ -2,17 +2,17 @@ pub enum NodeHandler { Number { number: f64 }, Function { function: fn(Vec) -> f64 }, - Variable { getter: fn() -> f64 }, + Variable, Empty, } impl NodeHandler { - pub fn run(&self, inputs: Vec) -> f64 { + pub fn run(&self, inputs: Vec, passed_x: f64) -> f64 { match self { NodeHandler::Number { number } => number.clone(), NodeHandler::Function { function } => function(inputs), - NodeHandler::Variable { getter } => getter(), - NodeHandler::Empty => 0f64, + NodeHandler::Variable => passed_x, + NodeHandler::Empty => inputs[0], } } } diff --git a/src/node/mod.rs b/src/node/mod.rs index 9288441..34dcad1 100644 --- a/src/node/mod.rs +++ b/src/node/mod.rs @@ -24,39 +24,46 @@ impl Node { max_children_count, } } - pub fn get_value(&self) -> f64 { - if self.children.len() == 0 { - return self.handler.run(vec![0f64]); - } - let mut inputs: Vec = vec![]; - for node in &self.children { - inputs.push(node.get_value()); - } - - return self.handler.run(inputs); - } - pub fn modify_tree<'a>(&'a mut self) -> NodeModifier<'a> { - NodeModifier::from_random(self, None) - } - pub fn number(n: f64) -> Node { - Node { + pub fn empty() -> Self { + Self { children: vec![], - handler: NodeHandler::Number { number: n }, + handler: NodeHandler::Empty, max_children_count: None, } } - pub fn function(func: fn(Vec) -> f64) -> Node { - Node { + pub fn number(n: f64) -> Self { + Self { children: vec![], - handler: NodeHandler::Function { function: func }, - max_children_count: Some(1), - } - } - pub fn variable(getter: fn() -> f64) -> Node { - Node { - children: vec![], - handler: NodeHandler::Variable { getter }, + handler: NodeHandler::Number { number: n }, max_children_count: Some(0), } } + pub fn function(func: fn(Vec) -> f64, max_children_count: Option) -> Self { + Self { + children: vec![], + handler: NodeHandler::Function { function: func }, + max_children_count, + } + } + pub fn variable() -> Self { + Self { + children: vec![], + handler: NodeHandler::Variable, + max_children_count: Some(0), + } + } + pub fn get_value(&self, passed_x: f64) -> f64 { + if self.children.len() == 0 { + return self.handler.run(vec![0f64], passed_x); + } + let mut inputs: Vec = vec![]; + for node in &self.children { + inputs.push(node.get_value(passed_x)); + } + + return self.handler.run(inputs, passed_x); + } + pub fn modify_tree(&mut self) -> NodeModifier { + NodeModifier::from_random(self, None) + } } diff --git a/src/node/node_modifier.rs b/src/node/node_modifier.rs index ac2f932..b2cd066 100644 --- a/src/node/node_modifier.rs +++ b/src/node/node_modifier.rs @@ -4,6 +4,7 @@ use crate::node::functions; use rand::random_range; const PICK_STOP_PROBABILITY: u8 = 2; +const TYPE_CHANGE_PROBABILITY: u8 = 10; pub enum NodeManipulationError { TooMuchChildren(Node), @@ -11,14 +12,18 @@ pub enum NodeManipulationError { pub struct NodeModifier<'a> { picked_node: &'a mut Node, - function_mutation_pool: Vec) -> f64>, + // This looks very monstrous, but it means "vector of functions for node paired with their maximum children count, if it exists" + function_mutation_pool: Vec<(fn(Vec) -> f64, Option)>, number_mutation_pool: Vec f64>, } impl<'a> NodeModifier<'a> { - fn get_standard_pool() -> (Vec) -> f64>, Vec f64>) { - let standard_function_mutation: Vec) -> f64> = vec![functions::sine]; - // *4, /4, *2, + fn get_standard_pool() -> ( + Vec<(fn(Vec) -> f64, Option)>, + Vec f64>, + ) { + let standard_function_mutation: Vec<(fn(Vec) -> f64, Option)> = + vec![(functions::sine, Some(1))]; let standard_number_mutation: Vec f64> = vec![ |x| x * 4f64, |x| x / 4.0f64, @@ -32,8 +37,11 @@ impl<'a> NodeModifier<'a> { //Builders pub fn from_random( root: &'a mut Node, - custom_pools: Option<(Vec) -> f64>, Vec f64>)>, - ) -> NodeModifier<'a> { + custom_pools: Option<( + Vec<(fn(Vec) -> f64, Option)>, + Vec f64>, + )>, + ) -> Self { let mut selected = root; while random_range(0..PICK_STOP_PROBABILITY) == PICK_STOP_PROBABILITY - 1 { let len = selected.children.len(); @@ -43,7 +51,7 @@ impl<'a> NodeModifier<'a> { selected = &mut selected.children[random_range(0..len)]; } let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool()); - NodeModifier { + Self { picked_node: selected, function_mutation_pool: pools.0, number_mutation_pool: pools.1, @@ -51,10 +59,13 @@ impl<'a> NodeModifier<'a> { } pub fn from_node( node: &'a mut Node, - custom_pools: Option<(Vec) -> f64>, Vec f64>)>, - ) -> NodeModifier<'a> { + custom_pools: Option<( + Vec<(fn(Vec) -> f64, Option)>, + Vec f64>, + )>, + ) -> Self { let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool()); - NodeModifier { + Self { picked_node: node, function_mutation_pool: pools.0, number_mutation_pool: pools.1, @@ -91,22 +102,27 @@ impl<'a> NodeModifier<'a> { } pub fn mutate_node(&mut self) { - match self.picked_node.handler { - NodeHandler::Number { number } => { - self.picked_node.handler = NodeHandler::Number { - number: (self.number_mutation_pool - [random_range(0..self.number_mutation_pool.len())])( - number - ), - }; - } - NodeHandler::Function { function } => { - self.picked_node.handler = NodeHandler::Function { - function: self.function_mutation_pool - [random_range(0..self.function_mutation_pool.len())], + if random_range(0..TYPE_CHANGE_PROBABILITY) == TYPE_CHANGE_PROBABILITY - 1 { + } else { + match self.picked_node.handler { + NodeHandler::Number { number } => { + self.picked_node.handler = NodeHandler::Number { + number: (self.number_mutation_pool + [random_range(0..self.number_mutation_pool.len())])( + number + ), + }; } + NodeHandler::Function { function } => { + let selected_mutation = &self.function_mutation_pool + [random_range(0..self.function_mutation_pool.len())]; + self.picked_node.max_children_count = selected_mutation.1; + self.picked_node.handler = NodeHandler::Function { + function: selected_mutation.0, + } + } + _ => {} } - _ => {} } } }