radiate_gp/collections/graphs/
chromosome.rs1use crate::{Factory, GraphNode, NodeStore, node::Node};
2use radiate_core::{Chromosome, Gene, Valid};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::{fmt::Debug, hash::Hash};
6
7#[derive(Clone)]
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66pub struct GraphChromosome<T> {
67 nodes: Vec<GraphNode<T>>,
68 store: Option<NodeStore<T>>,
69 max_nodes: Option<usize>,
70}
71
72impl<T> GraphChromosome<T> {
73 pub fn new(nodes: Vec<GraphNode<T>>, factory: NodeStore<T>) -> Self {
74 GraphChromosome {
75 nodes,
76 store: Some(factory),
77 max_nodes: None,
78 }
79 }
80
81 pub fn with_max_nodes(mut self, max_nodes: usize) -> Self {
82 self.max_nodes = Some(max_nodes + self.nodes.len());
83 self
84 }
85
86 pub fn take_nodes(&mut self) -> Vec<GraphNode<T>> {
87 std::mem::take(&mut self.nodes)
88 }
89
90 pub fn set_nodes(&mut self, nodes: Vec<GraphNode<T>>) {
91 self.nodes = nodes;
92 }
93
94 pub fn store(&self) -> Option<&NodeStore<T>> {
95 self.store.as_ref()
96 }
97
98 pub fn max_nodes(&self) -> Option<usize> {
99 self.max_nodes
100 }
101}
102
103impl<T> Factory<Option<NodeStore<T>>, GraphChromosome<T>> for GraphChromosome<T>
104where
105 T: Clone + PartialEq + Default,
106{
107 fn new_instance(&self, input: Option<NodeStore<T>>) -> GraphChromosome<T> {
108 input
109 .or_else(|| self.store.clone())
110 .map(|store| GraphChromosome {
111 nodes: self
112 .iter()
113 .enumerate()
114 .filter_map(|(index, node)| {
115 store
116 .new_instance((index, node.node_type()))
117 .map(|new_node| {
118 let mut new_node = if new_node.arity() == node.arity() {
119 node.with_allele(new_node.allele())
120 } else {
121 node.clone()
122 };
123
124 new_node.set_innovation(node.innovation());
125 new_node
126 })
127 })
128 .collect(),
129 store: Some(store),
130 max_nodes: self.max_nodes,
131 })
132 .map(|chromosome| {
133 if chromosome.len() != self.len() {
134 self.clone()
135 } else {
136 chromosome
137 }
138 })
139 .unwrap_or_else(|| self.clone())
140 }
141}
142
143impl<T: Clone> Chromosome for GraphChromosome<T> {
144 type Gene = GraphNode<T>;
145
146 fn get(&self, index: usize) -> Option<&Self::Gene> {
147 self.nodes.get(index)
148 }
149
150 fn get_mut(&mut self, index: usize) -> Option<&mut Self::Gene> {
151 self.nodes.get_mut(index)
152 }
153
154 fn set(&mut self, index: usize, gene: Self::Gene) {
155 if let Some(slot) = self.nodes.get_mut(index) {
156 *slot = gene;
157 }
158 }
159
160 fn iter(&self) -> impl Iterator<Item = &Self::Gene> {
161 self.nodes.iter()
162 }
163
164 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Self::Gene> {
165 self.nodes.iter_mut()
166 }
167
168 fn len(&self) -> usize {
169 self.nodes.len()
170 }
171}
172
173impl<T> Valid for GraphChromosome<T> {
174 #[inline]
175 fn is_valid(&self) -> bool {
176 self.nodes.iter().all(|gene| gene.is_valid())
177 }
178}
179
180impl<T> AsRef<[GraphNode<T>]> for GraphChromosome<T> {
181 fn as_ref(&self) -> &[GraphNode<T>] {
182 &self.nodes
183 }
184}
185
186impl<T> AsMut<[GraphNode<T>]> for GraphChromosome<T> {
187 fn as_mut(&mut self) -> &mut [GraphNode<T>] {
188 &mut self.nodes
189 }
190}
191
192impl<T: PartialEq> PartialEq for GraphChromosome<T> {
193 fn eq(&self, other: &Self) -> bool {
194 self.nodes == other.nodes
195 }
196}
197
198impl<T: Hash> Hash for GraphChromosome<T> {
199 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
200 for node in self.as_ref() {
201 node.hash(state);
202 }
203 }
204}
205
206impl<T> From<Vec<GraphNode<T>>> for GraphChromosome<T> {
207 fn from(nodes: Vec<GraphNode<T>>) -> Self {
208 GraphChromosome {
209 nodes,
210 store: None,
211 max_nodes: None,
212 }
213 }
214}
215
216impl<T, I> From<(I, NodeStore<T>)> for GraphChromosome<T>
217where
218 I: IntoIterator<Item = GraphNode<T>>,
219{
220 fn from((iter, store): (I, NodeStore<T>)) -> Self {
221 GraphChromosome {
222 nodes: iter.into_iter().collect(),
223 store: Some(store),
224 max_nodes: None,
225 }
226 }
227}
228
229impl<T> FromIterator<GraphNode<T>> for GraphChromosome<T> {
230 fn from_iter<I: IntoIterator<Item = GraphNode<T>>>(iter: I) -> Self {
231 GraphChromosome {
232 nodes: iter.into_iter().collect(),
233 store: None,
234 max_nodes: None,
235 }
236 }
237}
238
239impl<T> IntoIterator for GraphChromosome<T> {
240 type Item = GraphNode<T>;
241 type IntoIter = std::vec::IntoIter<GraphNode<T>>;
242
243 fn into_iter(self) -> Self::IntoIter {
244 self.nodes.into_iter()
245 }
246}
247
248impl<T: Debug> Debug for GraphChromosome<T> {
249 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
250 writeln!(f, "Graph {{")?;
251 for node in self.as_ref() {
252 writeln!(f, " {:?},", node)?;
253 }
254 write!(f, "}}")
255 }
256}