Skip to content

Commit a80fc9f

Browse files
committed
Update doc
Change Genotype mutability effects, add reset_scale_index() to be sure
1 parent 5607619 commit a80fc9f

File tree

12 files changed

+43
-52
lines changed

12 files changed

+43
-52
lines changed

CHANGELOG.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,29 @@ for later use, when zero-copy actually becomes viable.
2424

2525
Now the library is restructured to a simpler form, moving a lot of
2626
responsibilities away from `Genotype` which was becoming too heavy and
27-
centralized: All genes are now `Vec<Allele>` and stored on the `Chromosome`
27+
centralized: All genes are now `Vec<Allele>` and owned by the `Chromosome`
2828
(which now only has one implementation, no genotype specific variants anymore).
2929

3030
Chromosome recycling has been moved from the `Genotype` (`ChromosomeManager`)
3131
to the `Population`, the enabling flag is on `Genotype`. So when making custom
3232
implementations remember to use the population's `new_chromosome()`,
3333
`drop_chromomsome()`, `truncate()`, `truncate_external()` &
34-
`extend_from_within()` methods for the chromosomes.
35-
36-
However, `Genotype` unification proved impossible - each type has fundamentally
37-
different requirements. So the best route to allow for easier custom `Mutate`
38-
and `Crossover` implementations, was to make them user-genotype specific using
39-
an associated type `Genotype` on `Mutate` and `Crossover` traits (following
40-
existing `Fitness` pattern). The Genotypes now also have some
34+
`extend_from_within()` methods for the chromosomes. Or just disable the
35+
recycling (no risk of errors).
36+
37+
However, `Genotype` unification still proved impossible - each type has
38+
fundamentally different requirements. So the best route to allow for easier
39+
custom `Mutate` and `Crossover` implementations, was to make them user-genotype
40+
specific using an associated type `Genotype` on `Mutate` and `Crossover` traits
41+
(following existing `Fitness` pattern). The Genotypes now also have some
4142
implementation-specific helper methods to support custom implementations:
4243
`sample_allele()`, `sample_gene_delta()`, `sample_gene_index()`,
4344
`sample_gene_indices()`.
4445

4546
Skip the associated type `Genotype` on `Select` and `Extension` for now, as
4647
these mainly work with the chromosome metadata and are not genotype specific.
4748

48-
General usage by client is hardly impacted, most is internal.
49+
General usage by client has little impact, most is internal.
4950

5051
### Changed
5152
* Add associated type `Genotype` to `Mutate` and `Crossover` traits (following
@@ -55,16 +56,17 @@ General usage by client is hardly impacted, most is internal.
5556
trait responsible for the hashing implementation (with `impl_allele!` macro
5657
for default implementation)
5758
* Moved `current_scale_index` from `StrategyState` to `Genotype`. This is the
58-
only change towards `Genotype`. The scaling is only implemented by
59+
only change adding `Genotype` logic. The scaling is only implemented by
5960
`RangeGenotype` and `MultiRangeGenotype`, so it felt more genotype specific.
6061
It does make the `Genotype` mutable again, which is an accepted tradeoff.
6162

6263
### Removed
6364
* Remove matrix genotypes (`DynamicMatrixGenotype`, `StaticMatrixGenotype`)
6465
* Remove `ChromosomeManager` trait
66+
* Remove `GenesOwner` and `GenesPointer` traits
6567
* Remove `BitGenotype` - use `BinaryGenotype` with `Vec<bool>` instead
6668
* Remove `calculate_for_population()` as the population-level fitness calculation user
67-
hook. All is now `calculate_for_chromosome()`
69+
hook. All is now `calculate_for_chromosome()` which can now be compile time guarded
6870

6971
## [0.20.5] - 2025-05-21
7072
### Added

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ See [examples/evolve_large_genotype](../main/examples/evolve_large_genotype.rs)
158158

159159
Default configuration for correctness AND performance
160160
* .with_genes_hashing(true) // Required for proper GA dynamics
161-
* .with_chromosome_recycling(true) // Still worth it for large chromosomes
161+
* .with_chromosome_recycling(true) // Still worth it for large chromosomes, maybe disable for easier custom implementations
162162

163163
## Tests
164164
Run tests with `cargo test`

src/genotype.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub trait Genotype:
6464
fn builder() -> GenotypeBuilder<Self> {
6565
GenotypeBuilder::<Self>::default()
6666
}
67-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self;
67+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>);
6868
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>>;
6969

7070
fn max_scale_index(&self) -> Option<usize> {
@@ -73,6 +73,7 @@ pub trait Genotype:
7373
fn current_scale_index(&self) -> Option<usize> {
7474
None
7575
}
76+
fn reset_scale_index(&mut self) {}
7677
fn increment_scale_index(&mut self) -> bool {
7778
false
7879
}

src/genotype/binary.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,8 @@ impl Genotype for Binary {
107107
}
108108
chromosome.reset_metadata(self.genes_hashing);
109109
}
110-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
111-
let mut new = self.clone();
112-
new.seed_genes_list = seed_genes_list;
113-
new
110+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
111+
self.seed_genes_list = seed_genes_list;
114112
}
115113
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
116114
&self.seed_genes_list

src/genotype/list.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,8 @@ impl<T: Allele + PartialEq + Hash> Genotype for List<T> {
178178
}
179179
chromosome.reset_metadata(self.genes_hashing);
180180
}
181-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
182-
let mut new = self.clone();
183-
new.seed_genes_list = seed_genes_list;
184-
new
181+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
182+
self.seed_genes_list = seed_genes_list;
185183
}
186184
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
187185
&self.seed_genes_list

src/genotype/multi_list.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,8 @@ impl<T: Allele + PartialEq + Hash> Genotype for MultiList<T> {
204204
}
205205
chromosome.reset_metadata(self.genes_hashing);
206206
}
207-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
208-
let mut new = self.clone();
209-
new.seed_genes_list = seed_genes_list;
210-
new
207+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
208+
self.seed_genes_list = seed_genes_list;
211209
}
212210
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
213211
&self.seed_genes_list

src/genotype/multi_range.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,8 @@ where
276276
}
277277
chromosome.reset_metadata(self.genes_hashing);
278278
}
279-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
280-
let mut new = self.clone();
281-
new.seed_genes_list = seed_genes_list;
282-
new
279+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
280+
self.seed_genes_list = seed_genes_list;
283281
}
284282
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
285283
&self.seed_genes_list
@@ -296,6 +294,9 @@ where
296294
None
297295
}
298296
}
297+
fn reset_scale_index(&mut self) {
298+
self.current_scale_index = 0;
299+
}
299300
fn increment_scale_index(&mut self) -> bool {
300301
if let Some(max_scale_index) = self.max_scale_index() {
301302
if self.current_scale_index < max_scale_index {

src/genotype/multi_unique.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,8 @@ impl<T: Allele + Hash> Genotype for MultiUnique<T> {
237237
}
238238
chromosome.reset_metadata(self.genes_hashing);
239239
}
240-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
241-
let mut new = self.clone();
242-
new.seed_genes_list = seed_genes_list;
243-
new
240+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
241+
self.seed_genes_list = seed_genes_list;
244242
}
245243
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
246244
&self.seed_genes_list

src/genotype/range.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,8 @@ where
231231
}
232232
chromosome.reset_metadata(self.genes_hashing);
233233
}
234-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
235-
let mut new = self.clone();
236-
new.seed_genes_list = seed_genes_list;
237-
new
234+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
235+
self.seed_genes_list = seed_genes_list;
238236
}
239237
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
240238
&self.seed_genes_list
@@ -251,6 +249,9 @@ where
251249
None
252250
}
253251
}
252+
fn reset_scale_index(&mut self) {
253+
self.current_scale_index = 0;
254+
}
254255
fn increment_scale_index(&mut self) -> bool {
255256
if let Some(max_scale_index) = self.max_scale_index() {
256257
if self.current_scale_index < max_scale_index {

src/genotype/unique.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,8 @@ impl<T: Allele + Hash> Genotype for Unique<T> {
143143
}
144144
chromosome.reset_metadata(self.genes_hashing);
145145
}
146-
fn with_seed_genes_list(&self, seed_genes_list: Vec<Genes<Self::Allele>>) -> Self {
147-
let mut new = self.clone();
148-
new.seed_genes_list = seed_genes_list;
149-
new
146+
fn set_seed_genes_list(&mut self, seed_genes_list: Vec<Genes<Self::Allele>>) {
147+
self.seed_genes_list = seed_genes_list;
150148
}
151149
fn seed_genes_list(&self) -> &Vec<Genes<Self::Allele>> {
152150
&self.seed_genes_list

0 commit comments

Comments
 (0)