-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
80 lines (68 loc) · 2.3 KB
/
lib.rs
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
use rand::{RngCore, seq::SliceRandom, Rng};
pub use crate::{crossover::*, mutation::*, selection::*, chromosome::*, statistics::*};
use std::ops::Index;
pub mod chromosome;
pub mod crossover;
pub mod mutation;
pub mod selection;
pub mod statistics;
pub mod test;
/// A wrapping structure of the Genetic Algorithm, holding the evolution methods.
pub struct GeneticAlgorithm<S> {
selection_method: S,
crossover_method: Box<dyn CrossoverMethod>,
mutation_method: Box<dyn MutationMethod>
}
impl<S> GeneticAlgorithm<S>
where
S: SelectionMethod
{
pub fn new(
selection_method: S,
crossover_method: impl CrossoverMethod + 'static,
mutation_method: impl MutationMethod + 'static
) -> Self {
Self {
selection_method,
crossover_method: Box::new(crossover_method),
mutation_method: Box::new(mutation_method)
}
}
/// Given a population, selects, crosses over, and mutates each individual.
pub fn evolve<I>(&self, rng: &mut dyn RngCore, population: &[I]) -> (Vec<I>, Statistics)
where
I: Individual,
{
assert!(!population.is_empty());
let new_population: Vec<I> = (0..population.len())
.map(|_| {
// Selection of two random parents
let parent_a = self
.selection_method
.select(rng, population)
.chromosome();
let parent_b = self
.selection_method
.select(rng, population)
.chromosome();
// Crossover
let mut child = self
.crossover_method
.crossover(rng, parent_a, parent_b);
// Mutation
self.mutation_method.mutate(rng, &mut child);
// Convert the Chromosome back to an Individual
I::create(child)
})
.collect();
let stats = Statistics::new(population);
(new_population, stats)
}
}
/// An abstract individual, which holds chromosomes.
/// These chromosomes can be computed into a fitness function.
pub trait Individual {
fn fitness(&self) -> f32;
fn chromosome(&self) -> &Chromosome;
fn create(chromosome: Chromosome) -> Self;
}