|
1 | 1 | use super::builder::{Builder, TryFromBuilderError};
|
2 |
| -use super::{EvolveGenotype, Genotype, HillClimbGenotype, MutationType}; |
| 2 | +use super::{EvolveGenotype, Genotype, HillClimbGenotype, MutationType, PermutateGenotype}; |
3 | 3 | use crate::allele::RangeAllele;
|
4 | 4 | use crate::chromosome::{ChromosomeManager, GenesHash, GenesOwner, MultiRangeChromosome};
|
5 | 5 | use crate::population::Population;
|
@@ -574,6 +574,190 @@ where
|
574 | 574 | }
|
575 | 575 | }
|
576 | 576 |
|
| 577 | +impl<T: RangeAllele + Into<f64>> PermutateGenotype for MultiRange<T> |
| 578 | +where |
| 579 | + T: SampleUniform, |
| 580 | + Uniform<T>: Send + Sync, |
| 581 | +{ |
| 582 | + fn chromosome_permutations_into_iter<'a>( |
| 583 | + &'a self, |
| 584 | + chromosome: Option<&Self::Chromosome>, |
| 585 | + scale_index: Option<usize>, |
| 586 | + ) -> Box<dyn Iterator<Item = Self::Chromosome> + Send + 'a> { |
| 587 | + if self.seed_genes_list.is_empty() { |
| 588 | + match self.mutation_type { |
| 589 | + MutationType::Scaled => Box::new( |
| 590 | + self.permutable_gene_values_scaled(chromosome, scale_index.unwrap()) |
| 591 | + .into_iter() |
| 592 | + .multi_cartesian_product() |
| 593 | + .map(MultiRangeChromosome::new), |
| 594 | + ), |
| 595 | + MutationType::Relative => { |
| 596 | + panic!("RangeGenotype is not permutable for MutationType::Relative") |
| 597 | + } |
| 598 | + MutationType::Random => { |
| 599 | + panic!("RangeGenotype is not permutable for MutationType::Random") |
| 600 | + } |
| 601 | + } |
| 602 | + } else { |
| 603 | + Box::new( |
| 604 | + self.seed_genes_list |
| 605 | + .clone() |
| 606 | + .into_iter() |
| 607 | + .map(MultiRangeChromosome::new), |
| 608 | + ) |
| 609 | + } |
| 610 | + } |
| 611 | + |
| 612 | + fn chromosome_permutations_size(&self, scale_index: Option<usize>) -> BigUint { |
| 613 | + if self.seed_genes_list.is_empty() { |
| 614 | + match self.mutation_type { |
| 615 | + MutationType::Scaled => { |
| 616 | + let median_chromosome = self.median_chromosome(); |
| 617 | + self.permutable_gene_values_scaled( |
| 618 | + Some(&median_chromosome), |
| 619 | + scale_index.unwrap(), |
| 620 | + ) |
| 621 | + .iter() |
| 622 | + .map(|v| BigUint::from(v.len())) |
| 623 | + .product() |
| 624 | + } |
| 625 | + MutationType::Relative => { |
| 626 | + panic!("RangeGenotype is not permutable for MutationType::Relative") |
| 627 | + } |
| 628 | + MutationType::Random => { |
| 629 | + panic!("RangeGenotype is not permutable for MutationType::Random") |
| 630 | + } |
| 631 | + } |
| 632 | + } else { |
| 633 | + self.seed_genes_list.len().into() |
| 634 | + } |
| 635 | + } |
| 636 | + fn mutation_type_allows_permutation(&self) -> bool { |
| 637 | + match self.mutation_type { |
| 638 | + MutationType::Scaled => true, |
| 639 | + MutationType::Relative => false, |
| 640 | + MutationType::Random => false, |
| 641 | + } |
| 642 | + } |
| 643 | +} |
| 644 | + |
| 645 | +impl<T: RangeAllele + Into<f64>> MultiRange<T> |
| 646 | +where |
| 647 | + T: SampleUniform, |
| 648 | + Uniform<T>: Send + Sync, |
| 649 | +{ |
| 650 | + // scales should be symmetrical, so the step is simply the scale end |
| 651 | + pub fn permutable_gene_values_scaled( |
| 652 | + &self, |
| 653 | + chromosome: Option<&MultiRangeChromosome<T>>, |
| 654 | + scale_index: usize, |
| 655 | + ) -> Vec<Vec<T>> { |
| 656 | + self.allele_ranges |
| 657 | + .clone() |
| 658 | + .into_iter() |
| 659 | + .enumerate() |
| 660 | + .map(|(index, allele_range)| { |
| 661 | + let allele_range_start = *allele_range.start(); |
| 662 | + let allele_range_end = *allele_range.end(); |
| 663 | + |
| 664 | + let (allele_value_start, allele_value_end) = if let Some(chromosome) = chromosome { |
| 665 | + if let Some(previous_scale_index) = scale_index.checked_sub(1) { |
| 666 | + let working_range = &self.allele_mutation_scaled_ranges.as_ref().unwrap() |
| 667 | + [previous_scale_index][index]; |
| 668 | + |
| 669 | + let working_range_start = *working_range.start(); |
| 670 | + let working_range_end = *working_range.end(); |
| 671 | + |
| 672 | + let base_value = chromosome.genes[index]; |
| 673 | + let value_start = if base_value + working_range_start < allele_range_start { |
| 674 | + allele_range_start |
| 675 | + } else { |
| 676 | + base_value + working_range_start |
| 677 | + }; |
| 678 | + let value_end = if base_value + working_range_end > allele_range_end { |
| 679 | + allele_range_end |
| 680 | + } else { |
| 681 | + base_value + working_range_end |
| 682 | + }; |
| 683 | + |
| 684 | + (value_start, value_end) |
| 685 | + } else { |
| 686 | + (allele_range_start, allele_range_end) |
| 687 | + } |
| 688 | + } else { |
| 689 | + (allele_range_start, allele_range_end) |
| 690 | + }; |
| 691 | + |
| 692 | + let working_range = |
| 693 | + &self.allele_mutation_scaled_ranges.as_ref().unwrap()[scale_index][index]; |
| 694 | + let working_range_step = *working_range.end(); |
| 695 | + |
| 696 | + std::iter::successors(Some(allele_value_start), |value| { |
| 697 | + if *value < allele_value_end { |
| 698 | + let next_value = *value + working_range_step; |
| 699 | + if next_value > allele_value_end { |
| 700 | + Some(allele_value_end) |
| 701 | + } else { |
| 702 | + Some(next_value) |
| 703 | + } |
| 704 | + } else { |
| 705 | + None |
| 706 | + } |
| 707 | + }) |
| 708 | + .collect() |
| 709 | + }) |
| 710 | + .collect() |
| 711 | + } |
| 712 | + |
| 713 | + // pub fn permutable_gene_values_relative( |
| 714 | + // &self, |
| 715 | + // _chromosome: Option<&MultiRangeChromosome<T>>, |
| 716 | + // ) -> Vec<Vec<T>> { |
| 717 | + // panic!("MultiRangeGenotype is not permutable for MutationType::Relative"); |
| 718 | + // } |
| 719 | + // |
| 720 | + // pub fn permutable_gene_values_random( |
| 721 | + // &self, |
| 722 | + // _chromosome: Option<&MultiRangeChromosome<T>>, |
| 723 | + // ) -> Vec<Vec<T>> { |
| 724 | + // panic!("MultiRangeGenotype is not permutable for MutationType::Random"); |
| 725 | + // } |
| 726 | + |
| 727 | + pub fn median_chromosome(&self) -> MultiRangeChromosome<T> { |
| 728 | + let median_genes = self |
| 729 | + .allele_ranges |
| 730 | + .clone() |
| 731 | + .into_iter() |
| 732 | + .enumerate() |
| 733 | + .map(|(index, allele_range)| { |
| 734 | + let allele_range_start = *allele_range.start(); |
| 735 | + let allele_range_end = *allele_range.end(); |
| 736 | + |
| 737 | + let working_range = &self.allele_mutation_scaled_ranges.as_ref().unwrap()[0][index]; |
| 738 | + let working_range_step = *working_range.end(); |
| 739 | + |
| 740 | + let allele_value_iter = std::iter::successors(Some(allele_range_start), |value| { |
| 741 | + if *value < allele_range_end { |
| 742 | + let next_value = *value + working_range_step; |
| 743 | + if next_value > allele_range_end { |
| 744 | + Some(allele_range_end) |
| 745 | + } else { |
| 746 | + Some(next_value) |
| 747 | + } |
| 748 | + } else { |
| 749 | + None |
| 750 | + } |
| 751 | + }); |
| 752 | + |
| 753 | + let median_step = allele_value_iter.clone().count() / 2; |
| 754 | + allele_value_iter.clone().nth(median_step).unwrap() |
| 755 | + }) |
| 756 | + .collect(); |
| 757 | + MultiRangeChromosome::new(median_genes) |
| 758 | + } |
| 759 | +} |
| 760 | + |
577 | 761 | impl<T: RangeAllele + Into<f64>> ChromosomeManager<Self> for MultiRange<T>
|
578 | 762 | where
|
579 | 763 | T: SampleUniform,
|
|
0 commit comments