@@ -102,6 +102,16 @@ where
102102 let genes_size = builder. genes_size . unwrap ( ) ;
103103 let allele_range = builder. allele_range . unwrap ( ) ;
104104 let mutation_type = builder. mutation_type . unwrap_or ( MutationType :: Random ) ;
105+ let allele_sampler = match mutation_type {
106+ MutationType :: Discrete => {
107+ // [start, end+1) for uniform floor() sampling
108+ Uniform :: new ( * allele_range. start ( ) , * allele_range. end ( ) + T :: one ( ) )
109+ }
110+ _ => {
111+ // [start, end] for uniform sampling
112+ Uniform :: from ( allele_range. clone ( ) )
113+ }
114+ } ;
105115 let allele_bandwidth_sampler = match & mutation_type {
106116 MutationType :: Range ( bandwidth) => {
107117 Some ( Uniform :: new_inclusive ( T :: smallest_increment ( ) , bandwidth) )
@@ -118,7 +128,7 @@ where
118128 allele_range : allele_range. clone ( ) ,
119129 mutation_type,
120130 gene_index_sampler : Uniform :: from ( 0 ..genes_size) ,
121- allele_sampler : Uniform :: from ( allele_range . clone ( ) ) ,
131+ allele_sampler,
122132 allele_bandwidth_sampler,
123133 current_scale_index : 0 ,
124134 seed_genes_list : builder. seed_genes_list ,
@@ -137,15 +147,21 @@ where
137147 & self . mutation_type
138148 }
139149 pub fn sample_gene_random < R : Rng > ( & self , rng : & mut R ) -> T {
140- self . allele_sampler . sample ( rng)
150+ match self . mutation_type {
151+ MutationType :: Discrete => self . allele_sampler . sample ( rng) . floor ( ) ,
152+ _ => self . allele_sampler . sample ( rng) ,
153+ }
141154 }
142155
143156 // all delta's are positive, because we support unsigned integers as RangeAllele
144157 // quite the overhead to make this work, but I think it is worth it
145158 pub fn mutate_gene < R : Rng > ( & self , chromosome : & mut Chromosome < T > , index : usize , rng : & mut R ) {
146159 match & self . mutation_type {
147160 MutationType :: Random => {
148- chromosome. genes [ index] = self . sample_gene_random ( rng) ;
161+ chromosome. genes [ index] = self . allele_sampler . sample ( rng) ;
162+ }
163+ MutationType :: Discrete => {
164+ chromosome. genes [ index] = self . allele_sampler . sample ( rng) . floor ( ) ;
149165 }
150166 MutationType :: Range ( _) => {
151167 // post-clamp
@@ -178,7 +194,7 @@ where
178194 let allele_range_end = * self . allele_range . end ( ) ;
179195 if allele_range_end - allele_range_start <= bandwidth {
180196 // Random, leverage existing sampler
181- chromosome. genes [ index] = self . sample_gene_random ( rng) ;
197+ chromosome. genes [ index] = self . allele_sampler . sample ( rng) ;
182198 } else {
183199 // Bandwidth
184200 let current_value = chromosome. genes [ index] ;
@@ -219,9 +235,6 @@ where
219235 T :: clamped_sub ( current_value, delta, * self . allele_range . start ( ) ) ;
220236 }
221237 }
222- MutationType :: Discrete => {
223- panic ! ( "RangeGenotype has no implementation for MutationType::Discrete" )
224- }
225238 }
226239 }
227240}
@@ -454,7 +467,7 @@ where
454467 }
455468 }
456469 MutationType :: Discrete => {
457- panic ! ( "RangeGenotype has no implementation for MutationType::Discrete" )
470+ self . fill_neighbouring_population_discrete ( chromosome , population )
458471 }
459472 }
460473 }
@@ -583,6 +596,28 @@ where
583596 } ;
584597 } ) ;
585598 }
599+ fn fill_neighbouring_population_discrete (
600+ & self ,
601+ chromosome : & Chromosome < T > ,
602+ population : & mut Population < T > ,
603+ ) {
604+ let starting_value = self . allele_range . start ( ) . floor ( ) ;
605+ let ending_value = self . allele_range . end ( ) . floor ( ) ;
606+
607+ ( 0 ..self . genes_size ) . for_each ( |index| {
608+ let mut working_value = starting_value;
609+ let current_value = chromosome. genes [ index] . floor ( ) ;
610+ while working_value <= ending_value {
611+ if working_value != current_value {
612+ let mut new_chromosome = population. new_chromosome ( chromosome) ;
613+ new_chromosome. genes [ index] = working_value;
614+ new_chromosome. reset_metadata ( self . genes_hashing ) ;
615+ population. chromosomes . push ( new_chromosome) ;
616+ }
617+ working_value += T :: one ( ) ;
618+ }
619+ } ) ;
620+ }
586621}
587622
588623impl < T : RangeAllele > PermutateGenotype for Range < T >
@@ -604,6 +639,7 @@ where
604639 MutationType :: StepScaled ( steps) => {
605640 self . permutable_gene_values_step_scaled ( index, chromosome, steps)
606641 }
642+ MutationType :: Discrete => self . permutable_gene_values_discrete ( ) ,
607643 _ => {
608644 panic ! (
609645 "RangeGenotype is not permutable for {:?}" ,
@@ -649,7 +685,7 @@ where
649685 fn allows_permutation ( & self ) -> bool {
650686 matches ! (
651687 self . mutation_type,
652- MutationType :: Step ( _) | MutationType :: StepScaled ( _)
688+ MutationType :: Step ( _) | MutationType :: StepScaled ( _) | MutationType :: Discrete
653689 )
654690 }
655691}
@@ -713,6 +749,24 @@ where
713749 . collect ( )
714750 }
715751
752+ pub fn permutable_gene_values_discrete ( & self ) -> Vec < T > {
753+ let allele_value_start = self . allele_range . start ( ) . floor ( ) ;
754+ let allele_value_end = self . allele_range . end ( ) . floor ( ) ;
755+ std:: iter:: successors ( Some ( allele_value_start) , |value| {
756+ if * value < allele_value_end {
757+ let next_value = * value + T :: one ( ) ;
758+ if next_value > allele_value_end {
759+ Some ( allele_value_end)
760+ } else {
761+ Some ( next_value)
762+ }
763+ } else {
764+ None
765+ }
766+ } )
767+ . collect ( )
768+ }
769+
716770 pub fn chromosome_permutations_size_per_scale ( & self ) -> Vec < BigUint > {
717771 // first scale is affected by seed_genes_list
718772 let mut results = vec ! [ ] ;
@@ -774,6 +828,24 @@ where
774828 } )
775829 . count ( )
776830 }
831+ MutationType :: Discrete => {
832+ let allele_value_start = self . allele_range . start ( ) . floor ( ) ;
833+ let allele_value_end = self . allele_range . end ( ) . floor ( ) ;
834+
835+ std:: iter:: successors ( Some ( allele_value_start) , |value| {
836+ if * value < allele_value_end {
837+ let next_value = * value + T :: one ( ) ;
838+ if next_value > allele_value_end {
839+ Some ( allele_value_end)
840+ } else {
841+ Some ( next_value)
842+ }
843+ } else {
844+ None
845+ }
846+ } )
847+ . count ( )
848+ }
777849 _ => {
778850 panic ! (
779851 "RangeGenotype is not permutable for {:?}" ,
@@ -791,7 +863,19 @@ where
791863 Uniform < T > : Send + Sync ,
792864{
793865 fn clone ( & self ) -> Self {
794- let allele_sampler = Uniform :: from ( self . allele_range . clone ( ) ) ;
866+ let allele_sampler = match self . mutation_type {
867+ MutationType :: Discrete => {
868+ // [start, end+1) for uniform floor() sampling
869+ Uniform :: new (
870+ * self . allele_range . start ( ) ,
871+ * self . allele_range . end ( ) + T :: one ( ) ,
872+ )
873+ }
874+ _ => {
875+ // [start, end] for uniform sampling
876+ Uniform :: from ( self . allele_range . clone ( ) )
877+ }
878+ } ;
795879 let allele_bandwidth_sampler = match & self . mutation_type {
796880 MutationType :: Range ( bandwidth) => {
797881 Some ( Uniform :: new_inclusive ( T :: smallest_increment ( ) , bandwidth) )
0 commit comments