Pain - made to order
This commit is contained in:
parent
ae8e51c053
commit
5e61ee8e70
5 changed files with 95 additions and 61 deletions
|
|
@ -3,16 +3,21 @@ use crate::node::Node;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Formula {
|
pub struct Formula {
|
||||||
tree: Node,
|
tree: Node,
|
||||||
x: f64,
|
|
||||||
rating: f64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Formula {
|
impl Formula {
|
||||||
pub fn run(&mut self, inputs: Vec<f64>) -> Vec<f64> {
|
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<f64>) -> Vec<f64> {
|
||||||
let mut outputs: Vec<f64> = vec![];
|
let mut outputs: Vec<f64> = vec![];
|
||||||
for input in inputs {
|
for input in inputs {
|
||||||
self.x = input;
|
outputs.push(self.tree.get_value(input));
|
||||||
outputs.push(self.tree.get_value());
|
|
||||||
}
|
}
|
||||||
outputs
|
outputs
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
use crate::formula::Formula;
|
||||||
|
|
||||||
|
mod formula;
|
||||||
|
mod node;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
let formula = Formula::new();
|
||||||
|
dbg!(formula.run(vec![1f64]));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,17 @@
|
||||||
pub enum NodeHandler {
|
pub enum NodeHandler {
|
||||||
Number { number: f64 },
|
Number { number: f64 },
|
||||||
Function { function: fn(Vec<f64>) -> f64 },
|
Function { function: fn(Vec<f64>) -> f64 },
|
||||||
Variable { getter: fn() -> f64 },
|
Variable,
|
||||||
Empty,
|
Empty,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeHandler {
|
impl NodeHandler {
|
||||||
pub fn run(&self, inputs: Vec<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 } => function(inputs),
|
||||||
NodeHandler::Variable { getter } => getter(),
|
NodeHandler::Variable => passed_x,
|
||||||
NodeHandler::Empty => 0f64,
|
NodeHandler::Empty => inputs[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,39 +24,46 @@ impl Node {
|
||||||
max_children_count,
|
max_children_count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_value(&self) -> f64 {
|
pub fn empty() -> Self {
|
||||||
if self.children.len() == 0 {
|
Self {
|
||||||
return self.handler.run(vec![0f64]);
|
|
||||||
}
|
|
||||||
let mut inputs: Vec<f64> = 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 {
|
|
||||||
children: vec![],
|
children: vec![],
|
||||||
handler: NodeHandler::Number { number: n },
|
handler: NodeHandler::Empty,
|
||||||
max_children_count: None,
|
max_children_count: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn function(func: fn(Vec<f64>) -> f64) -> Node {
|
pub fn number(n: f64) -> Self {
|
||||||
Node {
|
Self {
|
||||||
children: vec![],
|
children: vec![],
|
||||||
handler: NodeHandler::Function { function: func },
|
handler: NodeHandler::Number { number: n },
|
||||||
max_children_count: Some(1),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn variable(getter: fn() -> f64) -> Node {
|
|
||||||
Node {
|
|
||||||
children: vec![],
|
|
||||||
handler: NodeHandler::Variable { getter },
|
|
||||||
max_children_count: Some(0),
|
max_children_count: Some(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn function(func: fn(Vec<f64>) -> f64, max_children_count: Option<usize>) -> 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<f64> = 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::node::functions;
|
||||||
use rand::random_range;
|
use rand::random_range;
|
||||||
|
|
||||||
const PICK_STOP_PROBABILITY: u8 = 2;
|
const PICK_STOP_PROBABILITY: u8 = 2;
|
||||||
|
const TYPE_CHANGE_PROBABILITY: u8 = 10;
|
||||||
|
|
||||||
pub enum NodeManipulationError {
|
pub enum NodeManipulationError {
|
||||||
TooMuchChildren(Node),
|
TooMuchChildren(Node),
|
||||||
|
|
@ -11,14 +12,18 @@ pub enum NodeManipulationError {
|
||||||
|
|
||||||
pub struct NodeModifier<'a> {
|
pub struct NodeModifier<'a> {
|
||||||
picked_node: &'a mut Node,
|
picked_node: &'a mut Node,
|
||||||
function_mutation_pool: Vec<fn(Vec<f64>) -> 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>) -> f64, Option<usize>)>,
|
||||||
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() -> (Vec<fn(Vec<f64>) -> f64>, Vec<fn(f64) -> f64>) {
|
fn get_standard_pool() -> (
|
||||||
let standard_function_mutation: Vec<fn(Vec<f64>) -> f64> = vec![functions::sine];
|
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
||||||
// *4, /4, *2,
|
Vec<fn(f64) -> f64>,
|
||||||
|
) {
|
||||||
|
let standard_function_mutation: Vec<(fn(Vec<f64>) -> f64, Option<usize>)> =
|
||||||
|
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,
|
||||||
|
|
@ -32,8 +37,11 @@ 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<(Vec<fn(Vec<f64>) -> f64>, Vec<fn(f64) -> f64>)>,
|
custom_pools: Option<(
|
||||||
) -> NodeModifier<'a> {
|
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
||||||
|
Vec<fn(f64) -> f64>,
|
||||||
|
)>,
|
||||||
|
) -> 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 {
|
||||||
let len = selected.children.len();
|
let len = selected.children.len();
|
||||||
|
|
@ -43,7 +51,7 @@ impl<'a> NodeModifier<'a> {
|
||||||
selected = &mut selected.children[random_range(0..len)];
|
selected = &mut selected.children[random_range(0..len)];
|
||||||
}
|
}
|
||||||
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
||||||
NodeModifier {
|
Self {
|
||||||
picked_node: selected,
|
picked_node: selected,
|
||||||
function_mutation_pool: pools.0,
|
function_mutation_pool: pools.0,
|
||||||
number_mutation_pool: pools.1,
|
number_mutation_pool: pools.1,
|
||||||
|
|
@ -51,10 +59,13 @@ impl<'a> NodeModifier<'a> {
|
||||||
}
|
}
|
||||||
pub fn from_node(
|
pub fn from_node(
|
||||||
node: &'a mut Node,
|
node: &'a mut Node,
|
||||||
custom_pools: Option<(Vec<fn(Vec<f64>) -> f64>, Vec<fn(f64) -> f64>)>,
|
custom_pools: Option<(
|
||||||
) -> NodeModifier<'a> {
|
Vec<(fn(Vec<f64>) -> f64, Option<usize>)>,
|
||||||
|
Vec<fn(f64) -> f64>,
|
||||||
|
)>,
|
||||||
|
) -> Self {
|
||||||
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
let pools = custom_pools.unwrap_or(NodeModifier::get_standard_pool());
|
||||||
NodeModifier {
|
Self {
|
||||||
picked_node: node,
|
picked_node: node,
|
||||||
function_mutation_pool: pools.0,
|
function_mutation_pool: pools.0,
|
||||||
number_mutation_pool: pools.1,
|
number_mutation_pool: pools.1,
|
||||||
|
|
@ -91,22 +102,27 @@ impl<'a> NodeModifier<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mutate_node(&mut self) {
|
pub fn mutate_node(&mut self) {
|
||||||
match self.picked_node.handler {
|
if random_range(0..TYPE_CHANGE_PROBABILITY) == TYPE_CHANGE_PROBABILITY - 1 {
|
||||||
NodeHandler::Number { number } => {
|
} else {
|
||||||
self.picked_node.handler = NodeHandler::Number {
|
match self.picked_node.handler {
|
||||||
number: (self.number_mutation_pool
|
NodeHandler::Number { number } => {
|
||||||
[random_range(0..self.number_mutation_pool.len())])(
|
self.picked_node.handler = NodeHandler::Number {
|
||||||
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())],
|
|
||||||
}
|
}
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue