1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#![allow(unused)]
extern crate rand;
use rand::Rng;
fn random() -> f64 {
rand::thread_rng().gen()
}
fn radint(num: usize) -> usize {
((num as f64) * random()) as usize
}
fn rex(start: usize, end: usize) -> usize {
start + radint(end - start)
}
pub struct Population<T: Genome> {
genomes: Vec<T>,
prob: Vec<f64>
}
impl<T: Genome> Population<T> {
pub fn new(size: usize) -> Self {
Self {
genomes: (0..size).map(|_| T::new()).collect(),
prob: Vec::new()
}
}
pub fn size(&self) -> usize {
self.genomes.len()
}
pub fn live(&mut self) {
let mut total_score = 0.;
let mut scores = Vec::with_capacity(self.size());
let mut fittest: &T = &self.genomes[0];
let mut max_score = 0.;
for genome in &self.genomes {
let score = genome.fitness();
scores.push(score);
total_score += score;
if score > max_score {
max_score = score;
fittest = genome;
}
}
scores.iter_mut().for_each(|val| *val = *val / total_score);
self.prob = scores;
fittest.display();
}
fn pick_one(&self) -> &T {
let mut r = random();
let mut index = 0;
while r > 0. {
r -= self.prob[index];
index += 1;
}
&self.genomes[index - 1]
}
pub fn next_generation(&mut self) {
self.genomes = (0..self.size())
.map(|_| self.pick_one().cross(self.pick_one()).mutate())
.collect();
}
}
pub trait Genome {
fn new() -> Self;
fn fitness(&self) -> f64;
fn cross(&self, other: &Self) -> Self;
fn mutate(self) -> Self;
fn display(&self);
}