Skip to content

Commit f4f5ae9

Browse files
committed
Add seed_genes cycling in Genotype population_constructor
1 parent 49f60c2 commit f4f5ae9

File tree

5 files changed

+191
-12
lines changed

5 files changed

+191
-12
lines changed

src/genotype.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,27 @@ pub trait EvolveGenotype: Genotype {
149149
population_size: usize,
150150
rng: &mut R,
151151
) -> Population<Self::Chromosome> {
152-
Population::new(
153-
(0..population_size)
154-
.map(|_| {
155-
let mut chromosome = self.chromosome_constructor_random(rng);
156-
chromosome.taint(self.calculate_genes_hash(&chromosome));
157-
chromosome
158-
})
159-
.collect::<Vec<_>>(),
160-
)
152+
if self.seed_genes_list().is_empty() {
153+
Population::new(
154+
(0..population_size)
155+
.map(|_| {
156+
let mut chromosome = self.chromosome_constructor_random(rng);
157+
chromosome.taint(self.calculate_genes_hash(&chromosome));
158+
chromosome
159+
})
160+
.collect::<Vec<_>>(),
161+
)
162+
} else {
163+
Population::new(
164+
self.seed_genes_list()
165+
.clone()
166+
.iter()
167+
.cycle()
168+
.take(population_size)
169+
.map(|genes| self.chromosome_constructor_genes(genes))
170+
.collect::<Vec<_>>(),
171+
)
172+
}
161173
}
162174

163175
/// Crossover genes between a pair of chromosomes.

src/genotype/builder.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ use std::ops::RangeInclusive;
66
/// See specfic [Genotype] for used options.
77
///
88
/// Shared initialization options for all Genotypes:
9-
/// * Builder `with_seed_genes_list(Vec<Genotype::Genes>)`, optional, list of start genes of all chromosomes
10-
/// which are distributed randomly in the population (instead of the default random genes).
11-
/// Sometimes it is efficient to start with a certain population
9+
/// * Builder `with_seed_genes_list(Vec<Genotype::Genes>)`, optional, list of start genes for
10+
/// chromosomes which are cycled into the starting population until the target_population_size is
11+
/// met (instead of the default random genes). Sometimes it is efficient to start with a certain
12+
/// population in the Evolve strategy. For the HillClimb strategy a single random seed genes is
13+
/// taken as the starting point (not cycling through them).
1214
///
1315
/// * Builder `with_genes_hashing(true)`, optional, store a genes_hash on the chromomose (in
1416
/// Evolve). This is needed when using `with_fitness_cache` on the strategy as key for the cache.

tests/genotype/binary_test.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,54 @@ fn chromosome_constructor_with_seed_genes_list() {
387387
);
388388
}
389389

390+
#[test]
391+
fn population_constructor_random() {
392+
let mut rng = SmallRng::seed_from_u64(0);
393+
let mut genotype = BinaryGenotype::builder()
394+
.with_genes_size(4)
395+
.build()
396+
.unwrap();
397+
genotype.chromosomes_setup();
398+
let population = genotype.population_constructor(5, &mut rng);
399+
println!("{:#?}", population.chromosomes);
400+
assert_eq!(
401+
inspect::population(&population),
402+
vec![
403+
vec![false, false, true, false],
404+
vec![true, true, true, false],
405+
vec![false, true, false, true],
406+
vec![true, false, true, false],
407+
vec![false, false, true, true],
408+
]
409+
)
410+
}
411+
412+
#[test]
413+
fn population_constructor_with_seed_genes_list() {
414+
let mut rng = SmallRng::seed_from_u64(0);
415+
let mut genotype = BinaryGenotype::builder()
416+
.with_genes_size(4)
417+
.with_seed_genes_list(vec![
418+
vec![true, true, false, false],
419+
vec![false, false, true, true],
420+
])
421+
.build()
422+
.unwrap();
423+
genotype.chromosomes_setup();
424+
let population = genotype.population_constructor(5, &mut rng);
425+
println!("{:#?}", population.chromosomes);
426+
assert_eq!(
427+
inspect::population(&population),
428+
vec![
429+
vec![true, true, false, false],
430+
vec![false, false, true, true],
431+
vec![true, true, false, false],
432+
vec![false, false, true, true],
433+
vec![true, true, false, false],
434+
]
435+
)
436+
}
437+
390438
#[test]
391439
fn chromosome_manager() {
392440
let rng = &mut SmallRng::seed_from_u64(0);

tests/genotype/dynamic_matrix_test.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,63 @@ fn chromosome_constructor_with_seed_genes_list() {
468468
));
469469
}
470470

471+
#[test]
472+
fn population_constructor_random() {
473+
let mut rng = SmallRng::seed_from_u64(0);
474+
let mut genotype = DynamicMatrixGenotype::builder()
475+
.with_genes_size(4)
476+
.with_allele_range(0.0..=1.0)
477+
.build()
478+
.unwrap();
479+
genotype.chromosomes_setup();
480+
let population = genotype.population_constructor(5, &mut rng);
481+
println!("{:#?}", population.chromosomes);
482+
assert!(relative_population_eq(
483+
population
484+
.chromosomes
485+
.iter()
486+
.map(|c| genotype.genes_slice(c).to_vec())
487+
.collect(),
488+
vec![
489+
vec![0.447, 0.439, 0.979, 0.462],
490+
vec![0.897, 0.942, 0.588, 0.456],
491+
vec![0.395, 0.818, 0.240, 0.976],
492+
vec![0.644, 0.054, 0.921, 0.225],
493+
vec![0.232, 0.296, 0.787, 0.724],
494+
],
495+
0.001
496+
));
497+
}
498+
499+
#[test]
500+
fn population_constructor_with_seed_genes_list() {
501+
let mut rng = SmallRng::seed_from_u64(0);
502+
let mut genotype = DynamicMatrixGenotype::builder()
503+
.with_genes_size(4)
504+
.with_allele_range(0.0..=1.0)
505+
.with_seed_genes_list(vec![vec![0.0, 0.1, 0.2, 0.3], vec![0.4, 0.5, 0.6, 0.7]])
506+
.build()
507+
.unwrap();
508+
genotype.chromosomes_setup();
509+
let population = genotype.population_constructor(5, &mut rng);
510+
println!("{:#?}", population.chromosomes);
511+
assert!(relative_population_eq(
512+
population
513+
.chromosomes
514+
.iter()
515+
.map(|c| genotype.genes_slice(c).to_vec())
516+
.collect(),
517+
vec![
518+
vec![0.0, 0.1, 0.2, 0.3],
519+
vec![0.4, 0.5, 0.6, 0.7],
520+
vec![0.0, 0.1, 0.2, 0.3],
521+
vec![0.4, 0.5, 0.6, 0.7],
522+
vec![0.0, 0.1, 0.2, 0.3],
523+
],
524+
0.001
525+
));
526+
}
527+
471528
#[test]
472529
fn chromosome_manager() {
473530
let rng = &mut SmallRng::seed_from_u64(0);

tests/genotype/static_matrix_test.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,66 @@ fn chromosome_constructor_with_seed_genes_list() {
473473
));
474474
}
475475

476+
#[test]
477+
fn population_constructor_random() {
478+
let mut rng = SmallRng::seed_from_u64(0);
479+
let mut genotype = StaticMatrixGenotype::<f32, 4, 5>::builder()
480+
.with_genes_size(4)
481+
.with_allele_range(0.0..=1.0)
482+
.build()
483+
.unwrap();
484+
genotype.chromosomes_setup();
485+
let population = genotype.population_constructor(5, &mut rng);
486+
println!("{:#?}", population.chromosomes);
487+
assert!(relative_population_eq(
488+
population
489+
.chromosomes
490+
.iter()
491+
.map(|c| genotype.genes_slice(c).to_vec())
492+
.collect(),
493+
vec![
494+
vec![0.447, 0.439, 0.979, 0.462],
495+
vec![0.897, 0.942, 0.588, 0.456],
496+
vec![0.395, 0.818, 0.240, 0.976],
497+
vec![0.644, 0.054, 0.921, 0.225],
498+
vec![0.232, 0.296, 0.787, 0.724],
499+
],
500+
0.001
501+
));
502+
}
503+
504+
#[test]
505+
fn population_constructor_with_seed_genes_list() {
506+
let mut rng = SmallRng::seed_from_u64(0);
507+
let mut genotype = StaticMatrixGenotype::<f32, 4, 5>::builder()
508+
.with_genes_size(4)
509+
.with_allele_range(0.0..=1.0)
510+
.with_seed_genes_list(vec![
511+
Box::new([0.0, 0.1, 0.2, 0.3]),
512+
Box::new([0.4, 0.5, 0.6, 0.7]),
513+
])
514+
.build()
515+
.unwrap();
516+
genotype.chromosomes_setup();
517+
let population = genotype.population_constructor(5, &mut rng);
518+
println!("{:#?}", population.chromosomes);
519+
assert!(relative_population_eq(
520+
population
521+
.chromosomes
522+
.iter()
523+
.map(|c| genotype.genes_slice(c).to_vec())
524+
.collect(),
525+
vec![
526+
vec![0.0, 0.1, 0.2, 0.3],
527+
vec![0.4, 0.5, 0.6, 0.7],
528+
vec![0.0, 0.1, 0.2, 0.3],
529+
vec![0.4, 0.5, 0.6, 0.7],
530+
vec![0.0, 0.1, 0.2, 0.3],
531+
],
532+
0.001
533+
));
534+
}
535+
476536
#[test]
477537
fn chromosome_manager() {
478538
let rng = &mut SmallRng::seed_from_u64(0);

0 commit comments

Comments
 (0)