Skip to main content

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