You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+6-22Lines changed: 6 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -73,8 +73,8 @@ impl Fitness for CountTrue {
73
73
// the search strategy
74
74
letevolve=Evolve::builder()
75
75
.with_genotype(genotype)
76
-
.with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order and drop excess population above target_population_size
77
-
.with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 40% parent selection (60% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
76
+
.with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order. Strive to replace 50% of the population with offspring. Allow 2% through the non-generational best chromosomes gate before selection and replacement
77
+
.with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 70% parent selection (30% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
78
78
.with_mutate(MutateSingleGene::new(0.2)) // mutate offspring for a single gene with a 20% probability per chromosome
79
79
.with_fitness(CountTrue) // count the number of true values in the chromosomes
80
80
.with_fitness_ordering(FitnessOrdering::Maximize) // optional, default is Maximize, aim towards the most true values
@@ -137,32 +137,16 @@ For the Evolve strategy:
137
137
sorting of some kind. This is relatively fast compared to the rest of the
138
138
operations.
139
139
* Crossover: the workhorse of internal parts. Crossover touches most genes each
140
-
generation and clones up to the whole population to restore lost population
141
-
size in selection. See performance tips below.
142
-
It also calculates new genes hashes if enabled on the Genotype,
143
-
which has a relatively high overhead on the main Evolve loop.
140
+
generation and clones up to the whole population to produce offspring
141
+
(depending on selection-rate). It also calculates
142
+
new genes hashes if enabled on the Genotype, which has a relatively high
143
+
overhead on the main Evolve loop.
144
144
* Mutate: no considerations. It touches genes like crossover does, but should
145
145
be used sparingly anyway; with low gene counts (<10%) and low probability (5-20%)
146
146
* Fitness: can be anything. This fully depends on the user domain. Parallelize
147
147
it using `with_par_fitness()` in the Builder. But beware that parallelization
148
148
has it's own overhead and is not always faster.
149
149
150
-
**Performance Tips**
151
-
* Small genes sizes
152
-
* It seems that CrossoverMultiGene with `number_of_crossovers = genes_size / 2`
153
-
and `allow_duplicates = true` is the best tradeoff between performance and
154
-
effect. CrossoverUniform is an alias for the same approach, taking the
155
-
genes_size from the genotype at runtime.
156
-
* Restoring the population doesn't matter that much as the cloning is
157
-
relatively less pronounced (but becomes more prominent for larger population
158
-
sizes)
159
-
* Large genes sizes
160
-
* It seems that CrossoverMultiPoint with `number_of_crossovers = genes_size / 9`
161
-
and `allow_duplicates = false` is the best tradeoff between performance and effect.
162
-
* Restoring the population has considerable performance effects.
163
-
Use a high selection_rate or even 100%, so there is little parent
164
-
cloning. Explore non-Vec based genotypes like BitGenotype.
165
-
166
150
**GPU acceleration**
167
151
168
152
There are two genotypes where Genes (N) and Population (M) are a stored in single contiguous
Copy file name to clipboardExpand all lines: src/lib.rs
+5-24Lines changed: 5 additions & 24 deletions
Original file line number
Diff line number
Diff line change
@@ -50,8 +50,8 @@
50
50
//! // the search strategy
51
51
//! let evolve = Evolve::builder()
52
52
//! .with_genotype(genotype)
53
-
//! .with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order and drop excess population above target_population_size
54
-
//! .with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 40% parent selection (60% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
53
+
//! .with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order. Strive to replace 50% of the population with offspring. Allow 2% through the non-generational best chromosomes gate before selection and replacement
54
+
//! .with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 70% parent selection (30% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
55
55
//! .with_mutate(MutateSingleGene::new(0.2)) // mutate offspring for a single gene with a 20% probability per chromosome
56
56
//! .with_fitness(CountTrue) // count the number of true values in the chromosomes
57
57
//! .with_fitness_ordering(FitnessOrdering::Maximize) // optional, default is Maximize, aim towards the most true values
@@ -118,34 +118,15 @@
118
118
//! sorting of some kind. This is relatively fast compared to the rest of the
119
119
//! operations.
120
120
//! * [Crossover](crossover): the workhorse of internal parts. Crossover touches most genes each
121
-
//! generation and clones up to the whole population to restore lost population size in selection.
122
-
//! See performance tips below.
123
-
//! It also calculates new genes hashes if enabled on the [Genotype](genotype), which has a
124
-
//! relatively high overhead on the main Evolve loop.
121
+
//! generation and clones up to the whole population to produce offspring (depending on
122
+
//! selection-rate). It also calculates new genes hashes if enabled on the [Genotype](genotype),
123
+
//! which has a relatively high overhead on the main Evolve loop.
125
124
//! * [Mutate](mutate): no considerations. It touches genes like crossover does, but should
126
125
//! be used sparingly anyway; with low gene counts (<10%) and low probability (5-20%)
127
126
//! * [Fitness](fitness): can be anything. This fully depends on the user domain. Parallelize
128
127
//! it using `with_par_fitness()` in the Builder. But beware that parallelization
129
128
//! has it's own overhead and is not always faster.
130
129
//!
131
-
//! **Performance Tips**
132
-
//!
133
-
//! * Small genes sizes
134
-
//! * It seems that [CrossoverMultiGene](crossover::CrossoverMultiGene) with
135
-
//! `number_of_crossovers = genes_size / 2` and `allow_duplicates = true`
136
-
//! is the best tradeoff between performance and effect.
137
-
//! [CrossoverUniform](crossover::CrossoverUniform) is an alias for the same approach,
138
-
//! taking the genes_size from the genotype at runtime.
139
-
//! * Restoring the population doesn't matter that much as the cloning is relatively less
140
-
//! pronounced (but becomes more prominent for larger population sizes)
141
-
//! * Large genes sizes
142
-
//! * It seems that [CrossoverMultiPoint](crossover::CrossoverMultiPoint) with
143
-
//! `number_of_crossovers = genes_size / 9` and `allow_duplicates = false` is
144
-
//! the best tradeoff between performance and effect.
145
-
//! * Restoring the population has considerable performance effects. Use a high
146
-
//! selection_rate or even 100%, so there is little parent cloning. Explore non-Vec based
147
-
//! genotypes like [BitGenotype](genotype::BitGenotype).
148
-
//!
149
130
//! **GPU acceleration**
150
131
//!
151
132
//! There are two genotypes where Genes (N) and Population (M) are a stored in single contiguous
Copy file name to clipboardExpand all lines: src/strategy.rs
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -40,9 +40,9 @@
40
40
//! // the search strategy (superset), steps marked (E)volve, (H)illClimb and (P)ermutate
41
41
//! let builder = StrategyBuilder::new()
42
42
//! .with_genotype(genotype) // (E,H,P) the genotype
43
-
//! .with_select(SelectElite::new(0.5, 0.02)) // (E) sort the chromosomes by fitness to determine crossover order and drop excess population above target_population_size
44
-
//! .with_extension(ExtensionMassExtinction::new(10, 0.1)) // (E) optional builder step, simulate cambrian explosion by mass extinction, when fitness score cardinality drops to 10 after the selection, trim to 10% of population
45
-
//! .with_crossover(CrossoverUniform::new(0.7, 0.8)) // (E) crossover all individual genes between 2 chromosomes for offspring with 40% parent selection (60% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
43
+
//! .with_select(SelectElite::new(0.5, 0.02)) // (E) sort the chromosomes by fitness to determine crossover order. Strive to replace 50% of the population with offspring. Allow 2% through the non-generational best chromosomes gate before selection and replacement
44
+
//! .with_extension(ExtensionMassExtinction::new(10, 0.1)) // (E) optional builder step, simulate cambrian explosion by mass extinction, when population cardinality drops to 10 after the selection, trim to 10% of population
45
+
//! .with_crossover(CrossoverUniform::new(0.7, 0.8)) // (E) crossover all individual genes between 2 chromosomes for offspring with 70% parent selection (30% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
46
46
//! .with_mutate(MutateSingleGene::new(0.2)) // (E) mutate offspring for a single gene with a 20% probability per chromosome
47
47
//! .with_fitness(CountTrue) // (E,H,P) count the number of true values in the chromosomes
48
48
//! .with_fitness_ordering(FitnessOrdering::Minimize) // (E,H,P) aim for the least true values
Copy file name to clipboardExpand all lines: src/strategy/evolve.rs
+34-3Lines changed: 34 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -53,6 +53,37 @@ pub enum EvolveVariant {
53
53
/// * max_stale_generations: when the ultimate goal in terms of fitness score is unknown and one depends on some convergion
54
54
/// threshold, or one wants a duration limitation next to the target_fitness_score
55
55
///
56
+
/// General Hyper-parameters:
57
+
/// * `replacement_rate` (selection): the target fraction of the population which exists of
58
+
/// children. Generational Replacement and Steady-State Replacement can both be
59
+
/// modelled with this parameter by setting it respectively to 1.0 and 0.2-0.8.
60
+
/// High values converge faster, but risk losing good solutions. Low values
61
+
/// convergence slower. If there is a shortage of population after the ideal
62
+
/// fraction, firstly remaining non-selected children and secondly remaining
63
+
/// non-selected parents will be used to fill the shortage to avoid population
64
+
/// collapse.
65
+
/// * `elitism_rate` (selection): a non-generational elite gate, which ensures passing of the
66
+
/// best chromosomes before selection and replacement takes place. Value should
67
+
/// typically be very low, between 0.01 and 0.05. Relevant for
68
+
/// `SelectTournament` where the best chromosome is not guaranteed to be
69
+
/// selected for a tournament if the `population_size` is larger than the
70
+
/// `target_population_size`
71
+
/// * `selection_rate` (crossover): the fraction of parents which are selected for
72
+
/// reproduction. This selection adds offspring to the population, the other
73
+
/// parents do not. The population now grows by the added offspring, as the
74
+
/// parents are not replaced yet. Value should typically be between 0.4 and
75
+
/// 0.8. High values risk of premature convergence. Low values reduce diversity
76
+
/// if overused.
77
+
/// * `crossover_rate (or recombination-rate)` (crossover): the fraction of selected parents
78
+
/// to crossover, the remaining parents just clone as offspring. Value should
79
+
/// typically be between 0.5 and 0.8. High values converge faster, but risk
80
+
/// losing good solutions. Low values have poor exploration and risk of
81
+
/// premature convergence
82
+
/// * `mutation_probability` (mutation): the fraction of offspring which gets mutated.
83
+
/// Typically low, between 0.01 and 0.10. High values reduces convergence
84
+
/// ability. Low have a risk of stagnation.
85
+
///
86
+
///
56
87
/// There are optional mutation distance limitations for
57
88
/// [RangeGenotype](crate::genotype::RangeGenotype) and
58
89
/// [MultiRangeGenotype](crate::genotype::MultiRangeGenotype) chromosomes. Listed in descending
@@ -114,9 +145,9 @@ pub enum EvolveVariant {
114
145
/// let evolve = Evolve::builder()
115
146
/// .with_genotype(genotype)
116
147
///
117
-
/// .with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order and drop excess population above target_population_size
118
-
/// .with_extension(ExtensionMassExtinction::new(10, 0.1)) // optional builder step, simulate cambrian explosion by mass extinction, when fitness score cardinality drops to 10 after the selection, trim to 10% of population
119
-
/// .with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 40% parent selection (60% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
148
+
/// .with_select(SelectElite::new(0.5, 0.02)) // sort the chromosomes by fitness to determine crossover order. Strive to replace 50% of the population with offspring. Allow 2% through the non-generational best chromosomes gate before selection and replacement
149
+
/// .with_extension(ExtensionMassExtinction::new(10, 0.1)) // optional builder step, simulate cambrian explosion by mass extinction, when population cardinality drops to 10 after the selection, trim to 10% of population
150
+
/// .with_crossover(CrossoverUniform::new(0.7, 0.8)) // crossover all individual genes between 2 chromosomes for offspring with 70% parent selection (30% do not produce offspring) and 80% chance of crossover (20% of parents just clone)
120
151
/// .with_mutate(MutateSingleGene::new(0.2)) // mutate offspring for a single gene with a 20% probability per chromosome
121
152
/// .with_fitness(CountTrue) // count the number of true values in the chromosomes
122
153
/// .with_fitness_ordering(FitnessOrdering::Minimize) // aim for the least true values
0 commit comments