This commit is contained in:
Rendo 2025-11-09 01:15:52 +05:00
commit 9c487308be
6 changed files with 127 additions and 11 deletions

View file

@ -1,4 +1,5 @@
use crate::node::Node;
use crate::node::node_modifier::NodeModifier;
#[derive(Clone)]
pub struct Formula {
@ -10,7 +11,7 @@ impl Formula {
let mut formula = Self {
tree: Node::empty(),
};
formula.tree.modify_tree().add_node(Node::variable());
formula.tree.modify_node().add_node(Node::variable());
formula
}
@ -22,4 +23,29 @@ impl Formula {
outputs
}
pub fn mutate(&mut self) {}
pub fn modify_tree(&mut self) -> NodeModifier {
self.tree.modify_tree()
}
pub fn display_tree(&self) {
self.display_recursion(0, vec![&self.tree]);
}
fn display_recursion(&self, indent_level: u8, nodes: Vec<&Node>) {
for node in nodes {
if indent_level != 0 {
for _ in 0..(indent_level) {
print!("|\t");
}
}
println!("{node}");
if node.children.len() == 0 {
continue;
}
let mut next_nodes: Vec<&Node> = Vec::new();
for node in &node.children {
next_nodes.push(node);
}
self.display_recursion(indent_level + 1, next_nodes);
}
}
}

View file

@ -1,2 +1,4 @@
mod formula;
mod node;
pub mod formula;
pub mod node;
#[cfg(test)]
mod tests;

View file

@ -1,9 +1,22 @@
use crate::formula::Formula;
use crate::{formula::Formula, node::Node};
mod formula;
mod node;
#[cfg(test)]
mod tests;
fn main() {
let formula = Formula::new();
dbg!(formula.run(vec![1f64]));
let mut formula = Formula::new();
formula
.modify_tree()
.insert_node(Node::function(|inputs| inputs.iter().sum(), Some(2)), None);
if let Err(x) = formula
.modify_tree()
.go_down(0)
.add_node(Node::number(1f64))
{
println!("{x}");
}
formula.display_tree();
let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]);
}

View file

@ -1,15 +1,17 @@
use std::fmt;
use crate::node::node_modifier::NodeModifier;
use handler::*;
mod functions;
mod handler;
mod node_modifier;
pub mod node_modifier;
#[derive(Clone)]
pub struct Node {
children: Vec<Node>,
handler: NodeHandler,
max_children_count: Option<usize>,
pub(crate) children: Vec<Node>,
pub(crate) handler: NodeHandler,
pub(crate) max_children_count: Option<usize>,
}
impl Node {
@ -63,7 +65,25 @@ impl Node {
return self.handler.run(inputs, passed_x);
}
pub fn modify_tree(&mut self) -> NodeModifier {
pub fn modify_node(&mut self) -> NodeModifier {
NodeModifier::from_random(self, None)
}
pub fn modify_tree(&mut self) -> NodeModifier {
NodeModifier::from_node(self, None)
}
}
impl fmt::Display for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self.handler {
NodeHandler::Number { number } => number.to_string(),
NodeHandler::Function { function } => "Function".to_string(),
NodeHandler::Variable => "X".to_string(),
NodeHandler::Empty => "Empty".to_string(),
}
)
}
}

View file

@ -1,3 +1,5 @@
use std::fmt;
use crate::node::Node;
use crate::node::NodeHandler;
use crate::node::functions;
@ -9,6 +11,17 @@ const TYPE_CHANGE_PROBABILITY: u8 = 10;
pub enum NodeManipulationError {
TooMuchChildren(Node),
}
impl fmt::Display for NodeManipulationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
NodeManipulationError::TooMuchChildren(node) => "Too much children",
}
)
}
}
pub struct NodeModifier<'a> {
picked_node: &'a mut Node,
@ -71,6 +84,10 @@ impl<'a> NodeModifier<'a> {
number_mutation_pool: pools.1,
}
}
pub fn go_down(mut self, to_child: usize) -> Self {
self.picked_node = &mut self.picked_node.children[to_child];
self
}
pub fn add_node(&mut self, node: Node) -> Result<(), NodeManipulationError> {
if let Some(x) = self.picked_node.max_children_count {

38
src/tests.rs Normal file
View file

@ -0,0 +1,38 @@
use crate::{formula::Formula, node::Node};
#[test]
fn test_node_variable() {
let formula = Formula::new();
let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]);
assert_eq!(results, vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64])
}
#[test]
fn test_plus_one() {
let mut formula = Formula::new();
assert!(
formula
.modify_tree()
.insert_node(Node::function(|inputs| inputs[0] + 1f64, Some(1)), None)
.is_err()
== false
);
let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]);
assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64])
}
#[test]
fn test_branch_sum() {
let mut formula = Formula::new();
assert!(
formula
.modify_tree()
.insert_node(Node::function(|inputs| inputs.iter().sum(), Some(2)), None)
.is_err()
== false
);
assert!(formula.modify_tree().add_node(Node::number(1f64)).is_err() == false);
formula.display_tree();
let results = formula.run(vec![0f64, 1f64, 2f64, 3f64, 4f64, 5f64]);
assert_eq!(results, vec![1f64, 2f64, 3f64, 4f64, 5f64, 6f64])
}