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
use super::Fitness;
use super::super::Population;
use super::super::{AstNode, Mutatable};
use super::crossover;
use super::mutate;
use rand::Rng;
pub struct Weights {
pub reproduce: u32,
pub mutate: u32,
pub crossover: u32,
pub tree_height: i32
}
pub fn evolve<P, F, S, R: Rng>(pop: Population<P, F>, weights: &Weights, rng: &mut R, selector: S) -> Population<P, F>
where P: AstNode+Clone+Mutatable+Sync,
F: Fitness+Send,
S: for<'a> Fn(&'a Population<P, F>, &mut Rng) -> &'a P
{
let mut ret = Population::new(pop.n(), pop.generation + 1);
while ret.n() < pop.n() {
pick![rng,
weights.reproduce, {
let winner = selector(&pop, rng);
ret.add(winner.clone());
},
weights.mutate, {
let winner = selector(&pop, rng);
let target_height = rng.next_u32() as i32 % weights.tree_height;
let mutation = mutate::mutate_tree(winner, target_height, rng);
ret.add(*mutation);
},
weights.crossover, {
if pop.n() < 2 { continue; }
let one = selector(&pop, rng);
let two = selector(&pop, rng);
let (child1, child2) = crossover::crossover_tree(one, two, rng);
ret.add(*child1);
ret.add(*child2);
}
];
}
ret
}