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
104
//! The mutation strategy, very important for avoiding local optimum lock-in. But don't overdo it,
//! as it degenerates the population too much if overused. Use a mutation probability generally between
//! 5% and 20%.
pub use MultiGene as MutateMultiGene;
pub use MultiGeneDynamic as MutateMultiGeneDynamic;
pub use MultiGeneRange as MutateMultiGeneRange;
pub use SingleGene as MutateSingleGene;
pub use SingleGeneDynamic as MutateSingleGeneDynamic;
pub use Wrapper as MutateWrapper;
use crate;
use crate;
use crateStrategyReporter;
use Rng;
/// This is just a shortcut for `Self::Genotype`
pub type MutateGenotype<M> = Genotype;
/// This is just a shortcut for `EvolveState<Self::Genotype>,`
pub type MutateEvolveState<M> = ;
/// This is just a shortcut
pub type MutateAllele<M> = Allele;
/// # Optional Custom User implementation (rarely needed)
///
/// For the user API, the Mutate Trait has an associated Genotype. This way the user can implement
/// a specialized Mutate alterative with access to the user's Genotype specific methods at hand.
///
/// # Example
/// ```rust
/// use genetic_algorithm::strategy::evolve::prelude::*;
/// use std::time::Instant;
/// use rand::Rng;
///
/// #[derive(Clone, Debug)]
/// struct CustomMutate; // or with fields
/// impl Mutate for CustomMutate {
/// type Genotype = MultiRangeGenotype<f32>;
///
/// fn call<R: Rng, SR: StrategyReporter<Genotype = Self::Genotype>>(
/// &mut self,
/// genotype: &Self::Genotype,
/// state: &mut EvolveState<Self::Genotype>,
/// config: &EvolveConfig,
/// reporter: &mut SR,
/// rng: &mut R,
/// ) {
/// let now = Instant::now();
///
/// // Skip the parents, iterate over the freshly crossovered offspring
/// for chromosome in state
/// .population
/// .chromosomes
/// .iter_mut()
/// .filter(|c| c.is_offspring())
/// {
/// // Custom logic, for instance mutate all genes with even index be a relative change
/// for even_index in (0..genotype.genes_size()).filter(|x| x % 2 == 0) {
/// // MultiRangeGenotype specific methods are available (this one does allele bounds checking as well)
/// let delta = genotype.sample_gene_delta(chromosome, even_index, rng);
/// chromosome.genes[even_index] += delta;
/// }
/// for odd_index in (0..genotype.genes_size()).filter(|x| x % 2 == 1) {
/// // MultiRangeGenotype specific methods are available (pure random sample)
/// let new_value = genotype.sample_gene_random(odd_index, rng);
/// chromosome.genes[odd_index] = new_value;
/// }
/// // Important!!! Remember to reset the chromosome metadata after manipulation
/// chromosome.reset_metadata(genotype.genes_hashing);
/// }
/// // Optionally, log one ore more events
/// reporter.on_mutate_event(
/// MutateEvent("MyEvent".to_string()),
/// genotype,
/// state,
/// config,
/// );
///
/// // Optionally, keep track of duration for reporting
/// state.add_duration(StrategyAction::Mutate, now.elapsed());
/// }
/// }
/// ```
;