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: AGENTS.md
+73-68Lines changed: 73 additions & 68 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ guidance, API reference, gotchas, and copy-paste templates.
7
7
8
8
-[Quick Start](#quick-start)
9
9
-[Critical: FitnessValue is isize](#critical-fitnessvalue-is-isize)
10
-
-[Copy-Paste Templates](#copy-paste-templates) (more in [AGENTS_TEMPLATES.md](AGENTS_TEMPLATES.md))
10
+
-[Copy-Paste Templates](#copy-paste-templates) (more in [AGENTS_TEMPLATES.md](https://github.com/basvanwesting/genetic-algorithm/blob/main/AGENTS_TEMPLATES.md))
11
11
-[Decision Matrix: Problem Type → Configuration](#decision-matrix-problem-type--configuration)
use genetic_algorithm::strategy::evolve::prelude::*;
34
34
```
35
35
@@ -59,7 +59,7 @@ process dominates any floating-point rounding.
59
59
60
60
For float-based fitness, scale to isize manually:
61
61
62
-
```rust
62
+
```rust,ignore
63
63
// divide by desired precision, then cast
64
64
let precision = 1e-5;
65
65
Some((score / precision) as FitnessValue)
@@ -75,7 +75,7 @@ Return `None` from `calculate_for_chromosome` to mark a chromosome as invalid
75
75
76
76
Minimal end-to-end example showing the general flow (genotype → fitness → strategy → result):
77
77
78
-
```rust
78
+
```rust,ignore
79
79
use genetic_algorithm::strategy::evolve::prelude::*;
80
80
81
81
#[derive(Clone, Debug)]
@@ -113,7 +113,7 @@ fn main() {
113
113
}
114
114
```
115
115
116
-
See [AGENTS_TEMPLATES.md](AGENTS_TEMPLATES.md) for more examples covering all
116
+
See [AGENTS_TEMPLATES.md](https://github.com/basvanwesting/genetic-algorithm/blob/main/AGENTS_TEMPLATES.md) for more examples covering all
117
117
genotype types, strategies, and patterns (call_repeatedly, HillClimb, Permutate, etc.).
118
118
119
119
## Decision Matrix: Problem Type → Configuration
@@ -142,28 +142,28 @@ When implementing `calculate_for_chromosome`, access genes via `chromosome.genes
142
142
|---|---|---|
143
143
|`BinaryGenotype`|`Vec<bool>`||
144
144
|`ListGenotype<T>`|`Vec<T>`| Default T = usize |
145
-
|`UniqueGenotype<T>`|`Vec<T>`| Default T = usize, all values unique |
145
+
|`UniqueGenotype<T>`|`Vec<T>`| Default T = usize, positional permutation (swap-only mutation), values do not have to be unique, they are only treated as such|
146
146
|`RangeGenotype<T>`|`Vec<T>`| Default T = f32 |
147
-
|`MultiListGenotype<T>`|`Vec<T>`| Default T = usize |
148
-
|`MultiUniqueGenotype<T>`|`Vec<T>`| Default T = usize, unique within each group |
147
+
|`MultiListGenotype<T>`|`Vec<T>`| Default T = usize, each gene has its own set of possible values|
148
+
|`MultiUniqueGenotype<T>`|`Vec<T>`| Default T = usize, positional permutation (swap-only mutation) within each group, values do not have to be unique, they are only treated as such|
149
149
|`MultiRangeGenotype<T>`|`Vec<T>`| Default T = f32, each gene has its own range |
150
150
151
151
### Which Strategy?
152
152
153
153
| Situation | Strategy | Why |
154
154
|---|---|---|
155
155
| General optimization |`Evolve`| Full GA with crossover + mutation |
156
-
| Single permutation (`UniqueGenotype`) |`HillClimb`| Standard crossovers swap genes between parents, breaking the uniqueness invariant. HillClimb uses neighbor generation instead. |
157
-
| Multi-group permutation (`MultiUniqueGenotype`) |`Evolve`| Point-based crossovers work at group boundaries without breaking within-group uniqueness. |
158
156
| Convex search space |`HillClimb`| Local search suffices |
159
-
| Small search space (<1M) |`Permutate`| Exhaustive, 100% guarantee |
157
+
| Small search space |`Permutate`| Exhaustive, 100% guarantee |
158
+
159
+
**Scaling warning:** Permutate evaluates all possible gene combinations in a stream, so no memory issues, but serious duration issues
160
160
161
161
### Which HillClimb Variant?
162
162
163
163
| Situation | Variant | Why |
164
164
|---|---|---|
165
-
|Small genome (<20 genes) |`SteepestAscent`| Evaluates all neighbors, guarantees best local move|
166
-
|Large genome (>20 genes) |`Stochastic` (default) | One random neighbor per step, fast iterations|
165
+
|Large genome |`Stochastic` (default) | One random neighbor per step, fast iterations|
166
+
|Small genome |`SteepestAscent`| Evaluates all neighbors, guarantees best local move|
167
167
| Plateau traversal needed |`Stochastic` + high `max_stale_generations`| Stochastic can escape via `replace_on_equal_fitness`|
168
168
| Exact local optimum needed |`SteepestAscent` + `call_repeatedly(n)`| Deterministic per start, multiple random restarts |
169
169
@@ -176,12 +176,12 @@ with `call_repeatedly` for genomes >20 genes.
|`call_par_repeatedly(n)`| Parallel version of above. Beware of double parallelization with_par_fitness |
577
+
|`call_speciated(n)`| Multiple runs seed a final refinement pass. Best for complex combinatorial problems, where characteristics of alternative refined solutions need combining|
578
+
|`call_par_speciated(n)`| Parallel version of above. Beware of double parallelization with_par_fitness |
576
579
577
580
**Call variant availability by builder:**
578
581
@@ -585,7 +588,9 @@ N-1 results.
585
588
|`call_par_speciated(n)`| yes | no | no | yes (falls back to `call_par_repeatedly`) |
586
589
587
590
Only Evolve performs true speciation (seeding a final run with best genes from
588
-
prior runs). Each run starts from a random population.
591
+
prior runs). Each run before the final run starts from a random population.
592
+
593
+
Permutate always falls back to `call()` for all variants.
589
594
590
595
Both `.call()` and `.build()` return `Result<_, TryFromEvolveBuilderError>`.
591
596
Builder validation catches: missing required fields and missing ending conditions.
0 commit comments