Functions now have names
This commit is contained in:
parent
dd1d7b8494
commit
0c097a72fb
5 changed files with 66 additions and 43 deletions
|
|
@ -1,10 +0,0 @@
|
||||||
pub fn sine(inputs: Vec<f64>) -> f64 {
|
|
||||||
inputs[0].sin()
|
|
||||||
}
|
|
||||||
pub fn sum(inputs: Vec<f64>) -> f64 {
|
|
||||||
let mut sum = 0f64;
|
|
||||||
for i in inputs {
|
|
||||||
sum += i;
|
|
||||||
}
|
|
||||||
sum
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone)]
|
||||||
pub enum NodeHandler {
|
pub enum NodeHandler {
|
||||||
Number { number: f64 },
|
Number {
|
||||||
Function { function: fn(Vec<f64>) -> f64 },
|
number: f64,
|
||||||
|
},
|
||||||
|
Function {
|
||||||
|
name: String,
|
||||||
|
function: fn(Vec<f64>) -> f64,
|
||||||
|
max_args: Option<usize>,
|
||||||
|
},
|
||||||
Variable,
|
Variable,
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +16,11 @@ impl NodeHandler {
|
||||||
pub fn run(&self, inputs: Vec<f64>, passed_x: f64) -> f64 {
|
pub fn run(&self, inputs: Vec<f64>, passed_x: f64) -> f64 {
|
||||||
match self {
|
match self {
|
||||||
NodeHandler::Number { number } => number.clone(),
|
NodeHandler::Number { number } => number.clone(),
|
||||||
NodeHandler::Function { function } => function(inputs),
|
NodeHandler::Function {
|
||||||
|
function,
|
||||||
|
name,
|
||||||
|
max_args,
|
||||||
|
} => function(inputs),
|
||||||
NodeHandler::Variable => passed_x,
|
NodeHandler::Variable => passed_x,
|
||||||
NodeHandler::Empty => inputs[0],
|
NodeHandler::Empty => inputs[0],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ use std::fmt;
|
||||||
use crate::node::node_modifier::NodeModifier;
|
use crate::node::node_modifier::NodeModifier;
|
||||||
use handler::*;
|
use handler::*;
|
||||||
|
|
||||||
mod functions;
|
|
||||||
mod handler;
|
mod handler;
|
||||||
pub mod node_modifier;
|
pub mod node_modifier;
|
||||||
|
|
||||||
|
|
@ -40,10 +39,18 @@ impl Node {
|
||||||
max_children_count: Some(0),
|
max_children_count: Some(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn function(func: fn(Vec<f64>) -> f64, max_children_count: Option<usize>) -> Self {
|
pub fn function(
|
||||||
|
func_name: String,
|
||||||
|
func: fn(Vec<f64>) -> f64,
|
||||||
|
max_children_count: Option<usize>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
children: vec![],
|
children: vec![],
|
||||||
handler: NodeHandler::Function { function: func },
|
handler: NodeHandler::Function {
|
||||||
|
name: func_name,
|
||||||
|
function: func,
|
||||||
|
max_args: max_children_count,
|
||||||
|
},
|
||||||
max_children_count,
|
max_children_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,9 +85,13 @@ impl fmt::Display for Node {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match self.handler {
|
match &self.handler {
|
||||||
NodeHandler::Number { number } => number.to_string(),
|
NodeHandler::Number { number } => number.to_string(),
|
||||||
NodeHandler::Function { function } => "Function".to_string(),
|
NodeHandler::Function {
|
||||||
|
function,
|
||||||
|
name,
|
||||||
|
max_args,
|
||||||
|
} => name.clone(),
|
||||||
NodeHandler::Variable => "X".to_string(),
|
NodeHandler::Variable => "X".to_string(),
|
||||||
NodeHandler::Empty => "Empty".to_string(),
|
NodeHandler::Empty => "Empty".to_string(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use std::fmt;
|
||||||
|
|
||||||
use crate::node::Node;
|
use crate::node::Node;
|
||||||
use crate::node::NodeHandler;
|
use crate::node::NodeHandler;
|
||||||
use crate::node::functions;
|
|
||||||
use rand::random_range;
|
use rand::random_range;
|
||||||
|
|
||||||
const PICK_STOP_PROBABILITY: u8 = 2;
|
const PICK_STOP_PROBABILITY: u8 = 2;
|
||||||
|
|
@ -26,17 +25,17 @@ impl fmt::Display for NodeManipulationError {
|
||||||
pub struct NodeModifier<'a> {
|
pub struct NodeModifier<'a> {
|
||||||
picked_node: &'a mut Node,
|
picked_node: &'a mut Node,
|
||||||
// This looks very monstrous, but it means "vector of functions for node paired with their maximum children count, if it exists"
|
// 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>) -> f64, Option<usize>)>,
|
function_mutation_pool: Vec<NodeHandler>,
|
||||||
number_mutation_pool: Vec<fn(f64) -> f64>,
|
number_mutation_pool: Vec<fn(f64) -> f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> NodeModifier<'a> {
|
impl<'a> NodeModifier<'a> {
|
||||||
fn get_standard_pool() -> (
|
fn get_standard_pool() -> (Vec<NodeHandler>, Vec<fn(f64) -> f64>) {
|
||||||
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
let standard_function_mutation: Vec<NodeHandler> = vec![NodeHandler::Function {
|
||||||
Vec<fn(f64) -> f64>,
|
name: "Sine".to_string(),
|
||||||
) {
|
function: |inputs| inputs[0].sin(),
|
||||||
let standard_function_mutation: Vec<(fn(Vec<f64>) -> f64, Option<usize>)> =
|
max_args: Some(1),
|
||||||
vec![(functions::sine, Some(1))];
|
}];
|
||||||
let standard_number_mutation: Vec<fn(f64) -> f64> = vec![
|
let standard_number_mutation: Vec<fn(f64) -> f64> = vec![
|
||||||
|x| x * 4f64,
|
|x| x * 4f64,
|
||||||
|x| x / 4.0f64,
|
|x| x / 4.0f64,
|
||||||
|
|
@ -50,10 +49,7 @@ impl<'a> NodeModifier<'a> {
|
||||||
//Builders
|
//Builders
|
||||||
pub fn from_random(
|
pub fn from_random(
|
||||||
root: &'a mut Node,
|
root: &'a mut Node,
|
||||||
custom_pools: Option<(
|
custom_pools: Option<(Vec<NodeHandler>, Vec<fn(f64) -> f64>)>,
|
||||||
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
|
||||||
Vec<fn(f64) -> f64>,
|
|
||||||
)>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut selected = root;
|
let mut selected = root;
|
||||||
while random_range(0..PICK_STOP_PROBABILITY) == PICK_STOP_PROBABILITY - 1 {
|
while random_range(0..PICK_STOP_PROBABILITY) == PICK_STOP_PROBABILITY - 1 {
|
||||||
|
|
@ -72,10 +68,7 @@ impl<'a> NodeModifier<'a> {
|
||||||
}
|
}
|
||||||
pub fn from_node(
|
pub fn from_node(
|
||||||
node: &'a mut Node,
|
node: &'a mut Node,
|
||||||
custom_pools: Option<(
|
custom_pools: Option<(Vec<NodeHandler>, Vec<fn(f64) -> f64>)>,
|
||||||
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
|
||||||
Vec<fn(f64) -> f64>,
|
|
||||||
)>,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -121,21 +114,30 @@ impl<'a> NodeModifier<'a> {
|
||||||
pub fn mutate_node(&mut self) {
|
pub fn mutate_node(&mut self) {
|
||||||
if random_range(0..TYPE_CHANGE_PROBABILITY) == TYPE_CHANGE_PROBABILITY - 1 {
|
if random_range(0..TYPE_CHANGE_PROBABILITY) == TYPE_CHANGE_PROBABILITY - 1 {
|
||||||
} else {
|
} else {
|
||||||
match self.picked_node.handler {
|
match &self.picked_node.handler {
|
||||||
NodeHandler::Number { number } => {
|
NodeHandler::Number { number } => {
|
||||||
self.picked_node.handler = NodeHandler::Number {
|
self.picked_node.handler = NodeHandler::Number {
|
||||||
number: (self.number_mutation_pool
|
number: (self.number_mutation_pool
|
||||||
[random_range(0..self.number_mutation_pool.len())])(
|
[random_range(0..self.number_mutation_pool.len())])(
|
||||||
number
|
number.clone()
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
NodeHandler::Function { function } => {
|
NodeHandler::Function {
|
||||||
|
function,
|
||||||
|
name,
|
||||||
|
max_args,
|
||||||
|
} => {
|
||||||
let selected_mutation = &self.function_mutation_pool
|
let selected_mutation = &self.function_mutation_pool
|
||||||
[random_range(0..self.function_mutation_pool.len())];
|
[random_range(0..self.function_mutation_pool.len())];
|
||||||
self.picked_node.max_children_count = selected_mutation.1;
|
if let NodeHandler::Function {
|
||||||
self.picked_node.handler = NodeHandler::Function {
|
name,
|
||||||
function: selected_mutation.0,
|
function,
|
||||||
|
max_args,
|
||||||
|
} = &selected_mutation
|
||||||
|
{
|
||||||
|
self.picked_node.max_children_count = max_args.clone();
|
||||||
|
self.picked_node.handler = selected_mutation.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
14
src/tests.rs
14
src/tests.rs
|
|
@ -13,7 +13,14 @@ fn test_plus_one() {
|
||||||
assert!(
|
assert!(
|
||||||
formula
|
formula
|
||||||
.modify_tree()
|
.modify_tree()
|
||||||
.insert_node(Node::function(|inputs| inputs[0] + 1f64, Some(1)), None)
|
.insert_node(
|
||||||
|
Node::function(
|
||||||
|
"+1".to_string(),
|
||||||
|
|inputs: Vec<f64>| inputs[0] + 1f64,
|
||||||
|
Some(1)
|
||||||
|
),
|
||||||
|
None
|
||||||
|
)
|
||||||
.is_err()
|
.is_err()
|
||||||
== false
|
== false
|
||||||
);
|
);
|
||||||
|
|
@ -27,7 +34,10 @@ fn test_branch_sum() {
|
||||||
assert!(
|
assert!(
|
||||||
formula
|
formula
|
||||||
.modify_tree()
|
.modify_tree()
|
||||||
.insert_node(Node::function(|inputs| inputs.iter().sum(), Some(2)), None)
|
.insert_node(
|
||||||
|
Node::function("Sum".to_string(), |inputs| inputs.iter().sum(), Some(2)),
|
||||||
|
None
|
||||||
|
)
|
||||||
.is_err()
|
.is_err()
|
||||||
== false
|
== false
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue