diff --git a/src/node/handler.rs b/src/node/handler.rs index 50254e3..1c86bc4 100644 --- a/src/node/handler.rs +++ b/src/node/handler.rs @@ -15,14 +15,14 @@ pub enum NodeHandler { impl NodeHandler { pub fn run(&self, inputs: Vec, passed_x: f64) -> f64 { match self { - NodeHandler::Number { number } => number.clone(), - NodeHandler::Function { + Self::Number { number } => number.clone(), + Self::Function { function, name, max_args, } => function(inputs), - NodeHandler::Variable => passed_x, - NodeHandler::Empty => inputs[0], + Self::Variable => passed_x, + Self::Empty => inputs[0], } } } diff --git a/src/node/node_modifier.rs b/src/node/node_modifier.rs index 1a40ac4..148e152 100644 --- a/src/node/node_modifier.rs +++ b/src/node/node_modifier.rs @@ -9,6 +9,9 @@ const TYPE_CHANGE_PROBABILITY: u8 = 10; pub enum NodeManipulationError { TooMuchChildren(Node), + NotEnoughChildren, + ProtectedEmpty, + IndexOutOfRange(usize), } impl fmt::Display for NodeManipulationError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -17,6 +20,9 @@ impl fmt::Display for NodeManipulationError { "{}", match self { NodeManipulationError::TooMuchChildren(node) => "Too much children", + NodeManipulationError::ProtectedEmpty => "Empty node is protected", + NodeManipulationError::NotEnoughChildren => "Not enough children", + NodeManipulationError::IndexOutOfRange(index) => "Index out of range", } ) } @@ -31,11 +37,43 @@ pub struct NodeModifier<'a> { impl<'a> NodeModifier<'a> { fn get_standard_pool() -> (Vec, Vec f64>) { - let standard_function_mutation: Vec = vec![NodeHandler::Function { - name: "Sine".to_string(), - function: |inputs| inputs[0].sin(), - max_args: Some(1), - }]; + let standard_function_mutation: Vec = vec![ + NodeHandler::Function { + name: "sin".to_string(), + function: |inputs| inputs[0].sin(), + max_args: Some(1), + }, + NodeHandler::Function { + name: "cos".to_string(), + function: |inputs| inputs[0].cos(), + max_args: Some(1), + }, + NodeHandler::Function { + name: "sum".to_string(), + function: |inputs| inputs.iter().sum(), + max_args: None, + }, + NodeHandler::Function { + name: "-".to_string(), + function: |inputs| -inputs[0], + max_args: Some(1), + }, + NodeHandler::Function { + name: "product".to_string(), + function: |inputs| inputs.iter().product(), + max_args: None, + }, + NodeHandler::Function { + name: "exp".to_string(), + function: |inputs| inputs[0].powf(inputs[1]), + max_args: Some(2), + }, + NodeHandler::Function { + name: "1/".to_string(), + function: |inputs| 1f64 / inputs[0], + max_args: Some(1), + }, + ]; let standard_number_mutation: Vec f64> = vec![ |x| x * 4f64, |x| x / 4.0f64, @@ -91,6 +129,27 @@ impl<'a> NodeModifier<'a> { self.picked_node.children.push(node); Ok(()) } + pub fn remove_node( + &mut self, + specified_index: Option, + ) -> Result<(), NodeManipulationError> { + if self.picked_node.children.len() == 0 { + return Err(NodeManipulationError::NotEnoughChildren); + } + match specified_index { + Some(index) => { + if self.picked_node.children.len() <= index { + return Err(NodeManipulationError::IndexOutOfRange(index)); + } + self.picked_node.children.remove(index); + Ok(()) + } + None => { + self.picked_node.children.remove(0); + Ok(()) + } + } + } pub fn insert_node( &mut self, @@ -113,6 +172,7 @@ impl<'a> NodeModifier<'a> { pub fn mutate_node(&mut self) { if random_range(0..TYPE_CHANGE_PROBABILITY) == TYPE_CHANGE_PROBABILITY - 1 { + self.change_node_type(None); } else { match &self.picked_node.handler { NodeHandler::Number { number } => { @@ -144,4 +204,39 @@ impl<'a> NodeModifier<'a> { } } } + pub fn change_node_type(&mut self, to: Option) { + self.picked_node.handler = to.unwrap_or(self.get_random_handler()); + } + pub fn get_random_handler(&self) -> NodeHandler { + let picked = random_range(0..4); + + if picked == 0 { + NodeHandler::Number { + number: random_range(0.0..=1e8f64), + } + } else if picked == 1 { + self.function_mutation_pool[random_range(0..self.function_mutation_pool.len())].clone() + } else if picked == 2 { + NodeHandler::Variable + } else { + NodeHandler::Empty + } + } + pub fn get_random_node(&self) -> Node { + let handler = self.get_random_handler(); + Node { + children: vec![], + handler: handler.clone(), + max_children_count: match handler { + NodeHandler::Number { number } => Some(0), + NodeHandler::Function { + name, + function, + max_args, + } => max_args, + NodeHandler::Variable => Some(0), + NodeHandler::Empty => Some(1), + }, + } + } }