radiate_core/genome/chromosomes/
bit.rs

1use crate::{Chromosome, Gene, Valid, random_provider};
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4use std::fmt::{Debug, Display};
5
6/// A gene that represents a single bit. The `allele` is a `bool` that is randomly assigned.
7/// The `allele` is either `true` or `false`. This is the simplest form of a gene and
8/// in traditional genetic algorithms is the gene that is used to represent the individuals.
9///
10/// # Example
11/// ``` rust
12/// use radiate_core::*;
13///
14/// // Craete a new BitGene from the allele `true`.
15/// let gene: BitGene = true.into();
16///
17/// // Create a new BitGene with a random allele.
18/// let gene = BitGene::new();
19///
20/// // Get the allele (bool) of the BitGene.
21/// let allele = gene.allele();
22///
23/// // Create a new BitGene from the allele.
24/// let gene = gene.with_allele(allele);
25/// ```
26///
27#[derive(Clone, PartialEq, Debug, Default)]
28#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
29pub struct BitGene {
30    allele: bool,
31}
32
33impl BitGene {
34    /// Create a new [`BitGene`] with a random allele.
35    pub fn new() -> Self {
36        BitGene {
37            allele: random_provider::bool(0.5),
38        }
39    }
40}
41
42/// Implement the [`Gene`] trait for the [`BitGene`].
43/// This allows the [`BitGene`] to be used in a [`Chromosome`] - specifically the
44/// [`BitChromosome`], thus allowing the [`BitGene`] to be used in the `GeneticEngine`.
45impl Gene for BitGene {
46    type Allele = bool;
47
48    fn allele(&self) -> &bool {
49        &self.allele
50    }
51
52    fn allele_mut(&mut self) -> &mut bool {
53        &mut self.allele
54    }
55
56    fn new_instance(&self) -> BitGene {
57        BitGene::new()
58    }
59
60    fn with_allele(&self, allele: &bool) -> BitGene {
61        BitGene { allele: *allele }
62    }
63}
64
65/// Because a [`BitGene`] is either `true` or `false` it is always valid.
66impl Valid for BitGene {}
67
68impl Display for BitGene {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        write!(f, "{}", if self.allele { 1 } else { 0 })
71    }
72}
73
74impl From<BitGene> for bool {
75    fn from(gene: BitGene) -> bool {
76        gene.allele
77    }
78}
79
80impl From<bool> for BitGene {
81    fn from(allele: bool) -> BitGene {
82        BitGene { allele }
83    }
84}
85
86/// A [`Chromosome`] that contains [`BitGene`].
87/// A [`BitChromosome`] is a collection of [`BitGene`] that represent the genetic
88/// material of an individual in the population.
89#[derive(Clone, PartialEq, Default, Debug)]
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
91pub struct BitChromosome {
92    genes: Vec<BitGene>,
93}
94
95impl BitChromosome {
96    /// Create a new [`BitChromosome`] with the given length.
97    /// The length is the number of genes in the chromosome.
98    pub fn new(length: usize) -> Self {
99        let genes = (0..length).map(|_| BitGene::new()).collect();
100        BitChromosome { genes }
101    }
102}
103
104impl Chromosome for BitChromosome {
105    type Gene = BitGene;
106
107    fn genes(&self) -> &[Self::Gene] {
108        &self.genes
109    }
110
111    fn genes_mut(&mut self) -> &mut [Self::Gene] {
112        &mut self.genes
113    }
114}
115
116/// Every `BitGene` is valid, so the `BitChromosome` is also valid.
117impl Valid for BitChromosome {
118    fn is_valid(&self) -> bool {
119        true
120    }
121}
122
123impl From<BitGene> for BitChromosome {
124    fn from(gene: BitGene) -> Self {
125        BitChromosome { genes: vec![gene] }
126    }
127}
128
129impl From<Vec<BitGene>> for BitChromosome {
130    fn from(genes: Vec<BitGene>) -> Self {
131        BitChromosome { genes }
132    }
133}
134
135impl From<Vec<bool>> for BitChromosome {
136    fn from(alleles: Vec<bool>) -> Self {
137        BitChromosome {
138            genes: alleles.into_iter().map(BitGene::from).collect(),
139        }
140    }
141}
142
143impl FromIterator<BitGene> for BitChromosome {
144    fn from_iter<I: IntoIterator<Item = BitGene>>(iter: I) -> Self {
145        BitChromosome {
146            genes: iter.into_iter().collect(),
147        }
148    }
149}
150
151impl IntoIterator for BitChromosome {
152    type Item = BitGene;
153    type IntoIter = std::vec::IntoIter<BitGene>;
154
155    fn into_iter(self) -> Self::IntoIter {
156        self.genes.into_iter()
157    }
158}
159
160#[cfg(test)]
161mod test {
162    use super::*;
163
164    #[test]
165    fn test_into() {
166        let gene = BitGene::new();
167        let copy = gene.clone();
168        let allele: bool = gene.into();
169        assert_eq!(allele, copy.allele);
170    }
171
172    #[test]
173    fn test_from() {
174        let gene = BitGene::new();
175        let copy = gene.clone();
176        let allele: BitGene = copy;
177        assert_eq!(allele, gene);
178    }
179
180    #[test]
181    fn test_from_allele() {
182        let gene = BitGene::new();
183        let copy = gene.clone();
184        let allele = gene.allele();
185        let new_gene = gene.with_allele(allele);
186        assert_eq!(new_gene, copy);
187    }
188
189    #[test]
190    #[cfg(feature = "serde")]
191    fn test_bit_gene_serialization() {
192        let gene = BitGene::new();
193        let serialized = serde_json::to_string(&gene).expect("Failed to serialize BitGene");
194        let deserialized: BitGene =
195            serde_json::from_str(&serialized).expect("Failed to deserialize BitGene");
196
197        let chromosome = BitChromosome::new(10);
198        let serialized_chromosome =
199            serde_json::to_string(&chromosome).expect("Failed to serialize BitChromosome");
200        let deserialized_chromosome: BitChromosome = serde_json::from_str(&serialized_chromosome)
201            .expect("Failed to deserialize BitChromosome");
202
203        assert_eq!(gene, deserialized);
204        assert_eq!(chromosome, deserialized_chromosome);
205    }
206}