Random nodes
This commit is contained in:
parent
80c9d47399
commit
76e1a17f6d
2 changed files with 104 additions and 9 deletions
|
|
@ -15,14 +15,14 @@ pub enum NodeHandler {
|
||||||
impl NodeHandler {
|
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(),
|
Self::Number { number } => number.clone(),
|
||||||
NodeHandler::Function {
|
Self::Function {
|
||||||
function,
|
function,
|
||||||
name,
|
name,
|
||||||
max_args,
|
max_args,
|
||||||
} => function(inputs),
|
} => function(inputs),
|
||||||
NodeHandler::Variable => passed_x,
|
Self::Variable => passed_x,
|
||||||
NodeHandler::Empty => inputs[0],
|
Self::Empty => inputs[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ const TYPE_CHANGE_PROBABILITY: u8 = 10;
|
||||||
|
|
||||||
pub enum NodeManipulationError {
|
pub enum NodeManipulationError {
|
||||||
TooMuchChildren(Node),
|
TooMuchChildren(Node),
|
||||||
|
NotEnoughChildren,
|
||||||
|
ProtectedEmpty,
|
||||||
|
IndexOutOfRange(usize),
|
||||||
}
|
}
|
||||||
impl fmt::Display for NodeManipulationError {
|
impl fmt::Display for NodeManipulationError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
|
@ -17,6 +20,9 @@ impl fmt::Display for NodeManipulationError {
|
||||||
"{}",
|
"{}",
|
||||||
match self {
|
match self {
|
||||||
NodeManipulationError::TooMuchChildren(node) => "Too much children",
|
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> {
|
impl<'a> NodeModifier<'a> {
|
||||||
fn get_standard_pool() -> (Vec<NodeHandler>, Vec<fn(f64) -> f64>) {
|
fn get_standard_pool() -> (Vec<NodeHandler>, Vec<fn(f64) -> f64>) {
|
||||||
let standard_function_mutation: Vec<NodeHandler> = vec![NodeHandler::Function {
|
let standard_function_mutation: Vec<NodeHandler> = vec![
|
||||||
name: "Sine".to_string(),
|
NodeHandler::Function {
|
||||||
|
name: "sin".to_string(),
|
||||||
function: |inputs| inputs[0].sin(),
|
function: |inputs| inputs[0].sin(),
|
||||||
max_args: Some(1),
|
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<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,
|
||||||
|
|
@ -91,6 +129,27 @@ impl<'a> NodeModifier<'a> {
|
||||||
self.picked_node.children.push(node);
|
self.picked_node.children.push(node);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn remove_node(
|
||||||
|
&mut self,
|
||||||
|
specified_index: Option<usize>,
|
||||||
|
) -> 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(
|
pub fn insert_node(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -113,6 +172,7 @@ 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 {
|
||||||
|
self.change_node_type(None);
|
||||||
} else {
|
} else {
|
||||||
match &self.picked_node.handler {
|
match &self.picked_node.handler {
|
||||||
NodeHandler::Number { number } => {
|
NodeHandler::Number { number } => {
|
||||||
|
|
@ -144,4 +204,39 @@ impl<'a> NodeModifier<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn change_node_type(&mut self, to: Option<NodeHandler>) {
|
||||||
|
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),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue