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
105
106
107
108
109
//! Self-adaptive mutation trait for Evolution Strategy sigma co-evolution.
//!
//! Implementors of this trait store per-dimension step-size parameters (σ)
//! alongside their DNA and update them via the log-normal rule on every
//! [`Mutation::SelfAdaptiveGaussian`](crate::operations::Mutation::SelfAdaptiveGaussian)
//! call.
use crateChromosomeT;
use Rng;
/// Opt-in trait enabling [`Mutation::SelfAdaptiveGaussian`](crate::operations::Mutation::SelfAdaptiveGaussian).
///
/// Each chromosome that implements `SelfAdaptive` stores a vector of strategy
/// parameters σ (one per gene dimension). These parameters are co-evolved with
/// the chromosome's genes using the standard Evolution Strategy log-normal update:
///
/// ```text
/// σ'_i = σ_i × exp(τ' × N(0,1)_global + τ × N_i(0,1)_local)
/// ```
///
/// where `τ` and `τ'` are the per-dimension and global learning rates, and the
/// result is clamped to `sigma_min` to prevent sigma collapse.
///
/// # Required methods
///
/// Implementors must provide `strategy_params()` and `set_strategy_params()`.
/// The `adapt_strategy_params()` update rule is provided as a default
/// implementation via the trait body, so implementors get it for free.
///
/// # Examples
///
/// ```rust
/// use genetic_algorithms::chromosomes::Range;
/// use genetic_algorithms::genotypes::Range as RangeGenotype;
/// use genetic_algorithms::traits::{LinearChromosome, SelfAdaptive};
/// use std::borrow::Cow;
///
/// let mut c = Range::<f64>::new();
/// c.set_dna(Cow::Owned(vec![RangeGenotype::new(0, vec![(0.0, 1.0)], 0.5)]));
/// assert_eq!(c.strategy_params(), &[1.0]);
///
/// c.set_strategy_params(vec![0.2]);
/// assert_eq!(c.strategy_params(), &[0.2]);
///
/// c.adapt_strategy_params(0.5, 0.5, 1e-5);
/// // After adaption, sigma may have changed but is still >= 1e-5
/// assert!(c.strategy_params()[0] >= 1e-5);
/// ```