rust_ga/
lib.rs

1#![allow(unused)]
2#![deny(missing_docs)]
3
4//! # Rust GA
5//! 
6//! A simple framework for testing genetic algorithms.
7
8mod ga;
9/// Module containing Population struct and Genome trait
10pub use ga::*;
11
12#[cfg(test)]
13mod tests {
14
15    use super::ga::*;
16
17    use rand::Rng;
18
19    fn random() -> f64 {
20        rand::thread_rng().gen()
21    }
22
23    fn radint(num: usize) -> usize {
24        ((num as f64) * random()) as usize
25    }
26
27    fn rex(start: usize, end: usize) -> usize {
28        start + radint(end - start)
29    }
30
31    const TARGET: [char; 20] = ['T', 'o', ' ', 'b', 'e', ',',
32        ' ', 'o', 'r', ' ', 'n', 'o', 't', ' ', 't', 'o', ' ', 'b', 'e', '.'];
33
34    use std::iter::once;
35    
36    fn random_char() -> char {
37        (rex(32, 122) as u8) as char
38    }
39
40    struct Gene {
41        text: [char; 20]
42    }
43
44    impl Genome for Gene {
45        fn new() -> Self {
46            let mut text = [0u8 as char; 20];
47            for i in 0..20 {
48                text[i] = random_char();
49            }
50            Self { text }
51        }
52
53        fn fitness(&self) -> f64 {
54            2f64.powf((0..20).map(|i| ((self.text[i] == TARGET[i]) as usize) as f64).sum())
55        }
56
57        fn cross(&self, other: &Self) -> Self {
58            let mut text = [0u8 as char; 20];
59            for i in 0..20 {
60                text[i] = match radint(2) {
61                    0 => self.text[i],
62                    1 => other.text[i],
63                    _ => random_char()
64                }
65            }
66
67            Self { text }
68        }
69
70        fn mutate(mut self) -> Self {
71            for i in 0..20 {
72                if random() < 0.01 {
73                    self.text[i] = random_char();
74                }
75            }
76            self
77        }
78
79        fn display(&self) {
80            let display_text: String = self.text.iter().cloned().collect();
81            println!("{}", display_text);
82        }
83    }
84
85    #[test]
86    fn test_shakespear() {
87        let mut population: Population<Gene> = Population::new(100);
88        for i in 0..1000 {
89            population.live();
90            population.next_generation();
91        }
92    }
93}