diff --git a/src/node/functions.rs b/src/node/functions.rs new file mode 100644 index 0000000..dc55816 --- /dev/null +++ b/src/node/functions.rs @@ -0,0 +1,10 @@ +pub fn sine(inputs: Vec) -> f64 { + inputs[0].sin() +} +pub fn sum(inputs: Vec) -> f64 { + let mut sum = 0f64; + for i in inputs { + sum += i; + } + sum +} diff --git a/src/node/mod.rs b/src/node/mod.rs index b88873f..ed5fd31 100644 --- a/src/node/mod.rs +++ b/src/node/mod.rs @@ -1,6 +1,7 @@ use crate::node::node_modifier::NodeModifier; use handler::*; +mod functions; mod handler; mod node_modifier; diff --git a/src/node/node_modifier.rs b/src/node/node_modifier.rs index 19dcfb3..5f8fd33 100644 --- a/src/node/node_modifier.rs +++ b/src/node/node_modifier.rs @@ -1,15 +1,35 @@ use crate::node::Node; +use crate::node::functions; +use crate::node::handler::NodeHandler; use rand::random_range; const PICK_STOP_PROBABILITY: u8 = 2; pub struct NodeModifier<'a> { picked_node: &'a mut Node, + function_mutation_pool: Vec) -> f64>, + 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, + let standard_number_mutation: Vec f64> = vec![ + |x| x * 4f64, + |x| x / 4.0f64, + |x| x * 2f64, + |x| x / 2.0f64, + |x| x + 1f64, + |x| x - 1f64, + ]; + return (standard_function_mutation, standard_number_mutation); + } //Builders - pub fn from_random(root: &'a mut Node) -> NodeModifier<'a> { + pub fn from_random( + root: &'a mut Node, + custom_pools: Option<(Vec) -> f64>, Vec f64>)>, + ) -> NodeModifier<'a> { let mut selected = root; while random_range(0..PICK_STOP_PROBABILITY) == PICK_STOP_PROBABILITY - 1 { let len = selected.children.len(); @@ -18,12 +38,23 @@ impl<'a> NodeModifier<'a> { } selected = &mut selected.children[random_range(0..len)]; } + let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool()); NodeModifier { picked_node: selected, + function_mutation_pool: pools.0, + number_mutation_pool: pools.1, } } - pub fn from_node(node: &'a mut Node) -> NodeModifier<'a> { - NodeModifier { picked_node: node } + pub fn from_node( + node: &'a mut Node, + custom_pools: Option<(Vec) -> f64>, Vec f64>)>, + ) -> NodeModifier<'a> { + let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool()); + NodeModifier { + picked_node: node, + function_mutation_pool: pools.0, + number_mutation_pool: pools.1, + } } pub fn add_node(&mut self, node: Node) { @@ -38,5 +69,23 @@ impl<'a> NodeModifier<'a> { self.picked_node.children.insert(operated_index, node); } - pub fn mutate_node(&mut self) {} + 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())], + } + } + _ => {} + } + } }