radiate_core/codecs/
char.rs

1use super::Codec;
2use crate::chromosomes::char;
3use crate::genome::CharGene;
4use crate::genome::Gene;
5use crate::genome::genotype::Genotype;
6use crate::{CharChromosome, Chromosome};
7use std::sync::Arc;
8
9/// A `Codec` for a `Genotype` of `CharGenes`. The `encode` function creates a `Genotype` with `num_chromosomes` chromosomes
10/// and `num_genes` genes per chromosome. The `decode` function creates a `String` from the `Genotype` where the `String`
11/// contains the alleles of the `CharGenes` in the chromosome.
12#[derive(Clone)]
13pub struct CharCodec<T = ()> {
14    num_chromosomes: usize,
15    num_genes: usize,
16    char_set: Arc<[char]>,
17    _marker: std::marker::PhantomData<T>,
18}
19
20impl<T> CharCodec<T> {
21    pub fn with_char_set(mut self, char_set: impl Into<Arc<[char]>>) -> Self {
22        self.char_set = char_set.into();
23        self
24    }
25}
26
27impl CharCodec<Vec<Vec<char>>> {
28    pub fn matrix(num_chromosomes: usize, num_genes: usize) -> Self {
29        CharCodec {
30            num_chromosomes,
31            num_genes,
32            char_set: char::ALPHABET.chars().collect::<Vec<char>>().into(),
33            _marker: std::marker::PhantomData,
34        }
35    }
36}
37
38impl CharCodec<Vec<char>> {
39    pub fn vector(num_genes: usize) -> Self {
40        CharCodec {
41            num_chromosomes: 1,
42            num_genes,
43            char_set: char::ALPHABET.chars().collect::<Vec<char>>().into(),
44            _marker: std::marker::PhantomData,
45        }
46    }
47}
48
49impl Codec<CharChromosome, Vec<Vec<char>>> for CharCodec<Vec<Vec<char>>> {
50    fn encode(&self) -> Genotype<CharChromosome> {
51        Genotype::new(
52            (0..self.num_chromosomes)
53                .map(|_| {
54                    CharChromosome::new(
55                        (0..self.num_genes)
56                            .map(|_| CharGene::new(Arc::clone(&self.char_set)))
57                            .collect::<Vec<CharGene>>(),
58                    )
59                })
60                .collect::<Vec<CharChromosome>>(),
61        )
62    }
63
64    fn decode(&self, genotype: &Genotype<CharChromosome>) -> Vec<Vec<char>> {
65        genotype
66            .iter()
67            .map(|chromosome| {
68                chromosome
69                    .iter()
70                    .map(|gene| *gene.allele())
71                    .collect::<Vec<char>>()
72            })
73            .collect::<Vec<Vec<char>>>()
74    }
75}
76
77impl Codec<CharChromosome, Vec<char>> for CharCodec<Vec<char>> {
78    fn encode(&self) -> Genotype<CharChromosome> {
79        Genotype::new(
80            (0..self.num_chromosomes)
81                .map(|_| {
82                    CharChromosome::new(
83                        (0..self.num_genes)
84                            .map(|_| CharGene::new(Arc::clone(&self.char_set)))
85                            .collect::<Vec<CharGene>>(),
86                    )
87                })
88                .collect::<Vec<CharChromosome>>(),
89        )
90    }
91
92    fn decode(&self, genotype: &Genotype<CharChromosome>) -> Vec<char> {
93        genotype
94            .iter()
95            .flat_map(|chromosome| {
96                chromosome
97                    .iter()
98                    .map(|gene| *gene.allele())
99                    .collect::<Vec<char>>()
100            })
101            .collect::<Vec<char>>()
102    }
103}
104
105impl Codec<CharChromosome, Vec<Vec<char>>> for Vec<CharChromosome> {
106    fn encode(&self) -> Genotype<CharChromosome> {
107        Genotype::from(
108            self.iter()
109                .map(|chromosome| {
110                    chromosome
111                        .iter()
112                        .map(|gene| gene.new_instance())
113                        .collect::<CharChromosome>()
114                })
115                .collect::<Vec<CharChromosome>>(),
116        )
117    }
118
119    fn decode(&self, genotype: &Genotype<CharChromosome>) -> Vec<Vec<char>> {
120        genotype
121            .iter()
122            .map(|chromosome| {
123                chromosome
124                    .iter()
125                    .map(|gene| *gene.allele())
126                    .collect::<Vec<char>>()
127            })
128            .collect::<Vec<Vec<char>>>()
129    }
130}
131
132impl Codec<CharChromosome, Vec<char>> for CharChromosome {
133    fn encode(&self) -> Genotype<CharChromosome> {
134        Genotype::from(
135            self.iter()
136                .map(|gene| gene.new_instance())
137                .collect::<CharChromosome>(),
138        )
139    }
140
141    fn decode(&self, genotype: &Genotype<CharChromosome>) -> Vec<char> {
142        genotype
143            .iter()
144            .flat_map(|chromosome| {
145                chromosome
146                    .iter()
147                    .map(|gene| *gene.allele())
148                    .collect::<Vec<char>>()
149            })
150            .collect::<Vec<char>>()
151    }
152}
153
154#[cfg(test)]
155mod tests {
156    use super::*;
157    use crate::Codec;
158    use crate::genome::Gene;
159
160    #[test]
161    fn test_char_codec_matrix() {
162        let char_set = "abcde".chars().collect::<Vec<char>>();
163        let codec = CharCodec::matrix(3, 5).with_char_set(char_set.clone());
164        let genotype = codec.encode();
165        assert_eq!(genotype.len(), 3);
166        assert_eq!(genotype[0].len(), 5);
167        for gene in genotype[0].iter() {
168            assert!(gene.char_set().eq(&char_set));
169            assert!(char_set.contains(gene.allele()));
170        }
171    }
172
173    #[test]
174    fn test_char_codec_vector() {
175        let codec = CharCodec::vector(5);
176        let genotype = codec.encode();
177        assert_eq!(genotype.len(), 1);
178        assert_eq!(genotype[0].len(), 5);
179        for gene in genotype[0].iter() {
180            assert!(codec.char_set.contains(gene.allele()));
181        }
182    }
183}