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> Chromosome for GraphChromosome<T>
144where
145 T: Clone + PartialEq,
146{
147 type Gene = GraphNode<T>;
148
149 fn as_slice(&self) -> &[GraphNode<T>] {
150 &self.nodes
151 }
152
153 fn as_mut_slice(&mut self) -> &mut [GraphNode<T>] {
154 &mut self.nodes
155 }
156}
157
158impl<T> Valid for GraphChromosome<T> {
159 #[inline]
160 fn is_valid(&self) -> bool {
161 self.nodes.iter().all(|gene| gene.is_valid())
162 }
163}
164
165impl<T> AsRef<[GraphNode<T>]> for GraphChromosome<T> {
166 fn as_ref(&self) -> &[GraphNode<T>] {
167 &self.nodes
168 }
169}
170
171impl<T> AsMut<[GraphNode<T>]> for GraphChromosome<T> {
172 fn as_mut(&mut self) -> &mut [GraphNode<T>] {
173 &mut self.nodes
174 }
175}
176
177impl<T: PartialEq> PartialEq for GraphChromosome<T> {
178 fn eq(&self, other: &Self) -> bool {
179 self.nodes == other.nodes
180 }
181}
182
183impl<T: Hash> Hash for GraphChromosome<T> {
184 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
185 for node in self.as_ref() {
186 node.hash(state);
187 }
188 }
189}
190
191impl<T> From<Vec<GraphNode<T>>> for GraphChromosome<T> {
192 fn from(nodes: Vec<GraphNode<T>>) -> Self {
193 GraphChromosome {
194 nodes,
195 store: None,
196 max_nodes: None,
197 }
198 }
199}
200
201impl<T, I> From<(I, NodeStore<T>)> for GraphChromosome<T>
202where
203 I: IntoIterator<Item = GraphNode<T>>,
204{
205 fn from((iter, store): (I, NodeStore<T>)) -> Self {
206 GraphChromosome {
207 nodes: iter.into_iter().collect(),
208 store: Some(store),
209 max_nodes: None,
210 }
211 }
212}
213
214impl<T> FromIterator<GraphNode<T>> for GraphChromosome<T> {
215 fn from_iter<I: IntoIterator<Item = GraphNode<T>>>(iter: I) -> Self {
216 GraphChromosome {
217 nodes: iter.into_iter().collect(),
218 store: None,
219 max_nodes: None,
220 }
221 }
222}
223
224impl<T> IntoIterator for GraphChromosome<T> {
225 type Item = GraphNode<T>;
226 type IntoIter = std::vec::IntoIter<GraphNode<T>>;
227
228 fn into_iter(self) -> Self::IntoIter {
229 self.nodes.into_iter()
230 }
231}
232
233impl<T: Debug> Debug for GraphChromosome<T> {
234 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235 writeln!(f, "Graph {{")?;
236 for node in self.as_ref() {
237 writeln!(f, " {:?},", node)?;
238 }
239 write!(f, "}}")
240 }
241}