radiate_gp/collections/trees/
node.rs

1use super::{Tree, TreeIterator};
2use crate::{Arity, NodeType, node::Node};
3use radiate::engines::genome::gene::{Gene, Valid};
4
5#[derive(PartialEq)]
6pub struct TreeNode<T> {
7    value: T,
8    arity: Option<Arity>,
9    children: Option<Vec<TreeNode<T>>>,
10}
11
12impl<T> TreeNode<T> {
13    pub fn new(val: T) -> Self {
14        TreeNode {
15            value: val,
16            arity: None,
17            children: None,
18        }
19    }
20
21    pub fn with_arity(val: T, arity: Arity) -> Self {
22        TreeNode {
23            value: val,
24            arity: Some(arity),
25            children: None,
26        }
27    }
28
29    pub fn with_children<N>(val: T, children: Vec<N>) -> Self
30    where
31        N: Into<TreeNode<T>>,
32    {
33        TreeNode {
34            value: val,
35            arity: None,
36            children: Some(children.into_iter().map(|n| n.into()).collect()),
37        }
38    }
39
40    pub fn is_leaf(&self) -> bool {
41        self.children.is_none()
42    }
43
44    pub fn add_child(&mut self, child: impl Into<TreeNode<T>>) {
45        let node = child.into();
46        if let Some(children) = self.children.as_mut() {
47            children.push(node);
48        } else {
49            self.children = Some(vec![node]);
50        }
51    }
52
53    pub fn attach(mut self, other: impl Into<TreeNode<T>>) -> Self {
54        self.add_child(other);
55        self
56    }
57
58    pub fn children(&self) -> Option<&Vec<TreeNode<T>>> {
59        self.children.as_ref()
60    }
61
62    pub fn children_mut(&mut self) -> Option<&mut Vec<TreeNode<T>>> {
63        self.children.as_mut()
64    }
65
66    pub fn size(&self) -> usize {
67        if let Some(children) = self.children.as_ref() {
68            children.iter().fold(1, |acc, child| acc + child.size())
69        } else {
70            1
71        }
72    }
73
74    pub fn height(&self) -> usize {
75        if let Some(children) = self.children.as_ref() {
76            1 + children
77                .iter()
78                .map(|child| child.height())
79                .max()
80                .unwrap_or(0)
81        } else {
82            0
83        }
84    }
85
86    pub fn swap_subtrees(&mut self, other: &mut TreeNode<T>, self_idx: usize, other_idx: usize) {
87        let self_subtree = self.get_mut(self_idx);
88        let other_subtree = other.get_mut(other_idx);
89
90        if let (Some(self_sub), Some(other_sub)) = (self_subtree, other_subtree) {
91            std::mem::swap(self_sub, other_sub);
92        }
93    }
94
95    pub fn get_mut(&mut self, index: usize) -> Option<&mut TreeNode<T>> {
96        if index == 0 {
97            return Some(self);
98        }
99
100        if let Some(children) = self.children.as_mut() {
101            let mut count = 0;
102            for child in children {
103                let size = child.size();
104                if index <= count + size {
105                    return child.get_mut(index - count - 1);
106                }
107                count += size;
108            }
109        }
110
111        None
112    }
113}
114
115impl<T> Node for TreeNode<T> {
116    type Value = T;
117
118    fn value(&self) -> &Self::Value {
119        &self.value
120    }
121
122    fn node_type(&self) -> NodeType {
123        if let Some(_) = self.children.as_ref() {
124            NodeType::Vertex
125        } else {
126            NodeType::Leaf
127        }
128    }
129
130    fn arity(&self) -> Arity {
131        if let Some(arity) = self.arity {
132            arity
133        } else {
134            if let Some(children) = self.children.as_ref() {
135                Arity::Exact(children.len())
136            } else {
137                match self.node_type() {
138                    NodeType::Leaf => Arity::Zero,
139                    NodeType::Vertex => Arity::Any,
140                    NodeType::Root => Arity::Any,
141                    _ => Arity::Zero,
142                }
143            }
144        }
145    }
146}
147
148impl<T> Gene for TreeNode<T>
149where
150    T: Clone + PartialEq + Default,
151{
152    type Allele = T;
153
154    fn allele(&self) -> &Self::Allele {
155        &self.value
156    }
157
158    fn new_instance(&self) -> Self {
159        TreeNode {
160            value: self.value.clone(),
161            arity: self.arity,
162            children: self.children.as_ref().map(|children| {
163                children
164                    .iter()
165                    .map(|child| child.new_instance())
166                    .collect::<Vec<TreeNode<T>>>()
167            }),
168        }
169    }
170
171    fn with_allele(&self, allele: &Self::Allele) -> Self {
172        TreeNode {
173            value: allele.clone(),
174            arity: self.arity,
175            children: self.children.as_ref().map(|children| children.to_vec()),
176        }
177    }
178}
179
180impl<T> Valid for TreeNode<T> {
181    fn is_valid(&self) -> bool {
182        for node in self.iter_breadth_first() {
183            match node.arity() {
184                Arity::Zero => {
185                    if node.children.is_some() {
186                        return false;
187                    }
188                }
189                Arity::Exact(n) => {
190                    if node.children.is_none()
191                        || node.children.as_ref().unwrap().len() != n as usize
192                    {
193                        return false;
194                    }
195                }
196                Arity::Any => {}
197            }
198        }
199
200        true
201    }
202}
203
204impl<T: Clone> Clone for TreeNode<T> {
205    fn clone(&self) -> Self {
206        TreeNode {
207            value: self.value.clone(),
208            arity: self.arity,
209            children: self.children.as_ref().map(|children| children.to_vec()),
210        }
211    }
212}
213
214impl<T> Into<Tree<T>> for TreeNode<T> {
215    fn into(self) -> Tree<T> {
216        Tree::new(self)
217    }
218}
219
220impl Into<TreeNode<i32>> for i32 {
221    fn into(self) -> TreeNode<i32> {
222        TreeNode::new(self)
223    }
224}
225
226impl Into<TreeNode<f64>> for f64 {
227    fn into(self) -> TreeNode<f64> {
228        TreeNode::new(self)
229    }
230}
231
232impl Into<TreeNode<String>> for String {
233    fn into(self) -> TreeNode<String> {
234        TreeNode::new(self)
235    }
236}
237
238impl Into<TreeNode<bool>> for bool {
239    fn into(self) -> TreeNode<bool> {
240        TreeNode::new(self)
241    }
242}
243
244impl Into<TreeNode<char>> for char {
245    fn into(self) -> TreeNode<char> {
246        TreeNode::new(self)
247    }
248}
249
250impl Into<TreeNode<usize>> for usize {
251    fn into(self) -> TreeNode<usize> {
252        TreeNode::new(self)
253    }
254}