Single genome modifications, genome move, tests
This commit is contained in:
parent
fc4d9d2ee3
commit
2692c4e151
3 changed files with 53 additions and 19 deletions
|
|
@ -2,29 +2,35 @@ use std::{collections::HashMap, mem::swap};
|
||||||
|
|
||||||
use rand::{RngExt, SeedableRng, rngs::StdRng};
|
use rand::{RngExt, SeedableRng, rngs::StdRng};
|
||||||
|
|
||||||
use crate::genetics::{gene::Gene, genome::*};
|
use crate::genetics::genome::*;
|
||||||
|
|
||||||
pub struct PairGenomeModificator {
|
pub struct PairGenomeModificator {
|
||||||
genome_a: Genome,
|
genome_a: Genome,
|
||||||
genome_b: Genome,
|
genome_b: Genome,
|
||||||
generator: StdRng
|
generator: StdRng
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct SingleGenomeModificator {
|
||||||
|
genome: Genome,
|
||||||
|
generator: StdRng
|
||||||
|
}
|
||||||
|
|
||||||
impl PairGenomeModificator {
|
impl PairGenomeModificator {
|
||||||
pub fn new(genome_a: &Genome,genome_b: &Genome) -> Self {
|
pub fn new(genome_a: Genome,genome_b: Genome) -> Self {
|
||||||
return Self {
|
return Self {
|
||||||
genome_a: genome_a.clone(),
|
genome_a,
|
||||||
genome_b: genome_b.clone(),
|
genome_b,
|
||||||
generator: rand::make_rng(),
|
generator: rand::make_rng(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub fn with_seed(genome_a: &Genome, genome_b: &Genome, seed: u64) -> Self {
|
pub fn with_seed(genome_a: Genome, genome_b: Genome, seed: u64) -> Self {
|
||||||
return Self {
|
return Self {
|
||||||
genome_a: genome_a.clone(),
|
genome_a,
|
||||||
genome_b: genome_b.clone(),
|
genome_b,
|
||||||
generator: StdRng::seed_from_u64(seed)
|
generator: StdRng::seed_from_u64(seed)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub fn allelic_crossingover(&mut self,chance: Option<u8>) {
|
pub fn allelic_crossingover(mut self,chance: Option<u8>) -> (Genome, Genome) {
|
||||||
let amount: usize = *[self.genome_a.graph.len(),self.genome_b.graph.len()].iter().min().unwrap_or(&0);
|
let amount: usize = *[self.genome_a.graph.len(),self.genome_b.graph.len()].iter().min().unwrap_or(&0);
|
||||||
|
|
||||||
for i in 0..amount {
|
for i in 0..amount {
|
||||||
|
|
@ -32,11 +38,12 @@ impl PairGenomeModificator {
|
||||||
if computed != 0 {continue;}
|
if computed != 0 {continue;}
|
||||||
swap(&mut self.genome_a.graph[i].0, &mut self.genome_b.graph[i].0);
|
swap(&mut self.genome_a.graph[i].0, &mut self.genome_b.graph[i].0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(self.genome_a,self.genome_b)
|
||||||
}
|
}
|
||||||
pub fn categoric_crossingover(&mut self, chance: Option<u8>) {
|
pub fn categoric_crossingover(mut self, chance: Option<u8>) -> (Genome,Genome) {
|
||||||
let threshold = chance.unwrap_or(2).max(2);
|
let threshold = chance.unwrap_or(2).max(2);
|
||||||
|
|
||||||
// Собираем индексы по категориям для каждого генома
|
|
||||||
let mut categories_a: HashMap<String, Vec<usize>> = HashMap::new();
|
let mut categories_a: HashMap<String, Vec<usize>> = HashMap::new();
|
||||||
let mut categories_b: HashMap<String, Vec<usize>> = HashMap::new();
|
let mut categories_b: HashMap<String, Vec<usize>> = HashMap::new();
|
||||||
|
|
||||||
|
|
@ -47,7 +54,6 @@ impl PairGenomeModificator {
|
||||||
categories_b.entry(gene.place.clone()).or_default().push(i);
|
categories_b.entry(gene.place.clone()).or_default().push(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проходим по категориям которые есть в обоих геномах
|
|
||||||
for (category, indices_a) in &categories_a {
|
for (category, indices_a) in &categories_a {
|
||||||
let Some(indices_b) = categories_b.get(category) else { continue; };
|
let Some(indices_b) = categories_b.get(category) else { continue; };
|
||||||
|
|
||||||
|
|
@ -57,14 +63,32 @@ impl PairGenomeModificator {
|
||||||
let fi = indices_a[self.generator.random_range(0..indices_a.len())];
|
let fi = indices_a[self.generator.random_range(0..indices_a.len())];
|
||||||
let si = indices_b[self.generator.random_range(0..indices_b.len())];
|
let si = indices_b[self.generator.random_range(0..indices_b.len())];
|
||||||
|
|
||||||
// Копируем и меняем местами
|
|
||||||
let gene_a = self.genome_a.graph[fi].0.clone();
|
let gene_a = self.genome_a.graph[fi].0.clone();
|
||||||
let gene_b = self.genome_b.graph[si].0.clone();
|
let gene_b = self.genome_b.graph[si].0.clone();
|
||||||
self.genome_a.graph[fi].0 = gene_b;
|
self.genome_a.graph[fi].0 = gene_b;
|
||||||
self.genome_b.graph[si].0 = gene_a;
|
self.genome_b.graph[si].0 = gene_a;
|
||||||
}
|
}
|
||||||
|
(self.genome_a,self.genome_b)
|
||||||
}
|
}
|
||||||
pub fn finish(self) -> (Genome,Genome) {
|
pub fn combine(mut self) -> (Genome,Genome){
|
||||||
|
(self.genome_a,self.genome_b)
|
||||||
|
}
|
||||||
|
pub fn cancel(self) -> (Genome,Genome) {
|
||||||
(self.genome_a,self.genome_b)
|
(self.genome_a,self.genome_b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SingleGenomeModificator {
|
||||||
|
pub fn new(genome: Genome) -> Self {
|
||||||
|
return Self {
|
||||||
|
genome,
|
||||||
|
generator: rand::make_rng(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub fn with_seed(genome: Genome, seed: u64) -> Self {
|
||||||
|
return Self {
|
||||||
|
genome,
|
||||||
|
generator: StdRng::seed_from_u64(seed)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ pub fn peashooter_template() -> Genome {
|
||||||
Gene::new("Peashooter","root", GeneType::pure_producer(|_|{Flow::empty()})),
|
Gene::new("Peashooter","root", GeneType::pure_producer(|_|{Flow::empty()})),
|
||||||
Gene::new("Peashooter","stem", GeneType::fill_all()),
|
Gene::new("Peashooter","stem", GeneType::fill_all()),
|
||||||
Gene::new("Peashooter","head",GeneType::random_distribution()),
|
Gene::new("Peashooter","head",GeneType::random_distribution()),
|
||||||
Gene::new("Peashooter","leaf",GeneType::modifier(|_|{None})),
|
Gene::new("Peashooter","leaf",GeneType::modifier(|_|{Flow::empty()})),
|
||||||
Gene::new("Peashooter","face",GeneType::consumer(|_|{}))
|
Gene::new("Peashooter","face",GeneType::consumer(|_|{}))
|
||||||
],vec![
|
],vec![
|
||||||
(0,1),
|
(0,1),
|
||||||
|
|
@ -19,7 +19,7 @@ pub fn sunflower_template() -> Genome {
|
||||||
Genome::from_edges(vec![
|
Genome::from_edges(vec![
|
||||||
Gene::new("Sunflower","root", GeneType::Dummy),
|
Gene::new("Sunflower","root", GeneType::Dummy),
|
||||||
Gene::new("Sunflower","stem", GeneType::Dummy),
|
Gene::new("Sunflower","stem", GeneType::Dummy),
|
||||||
Gene::new("Sunflower","head", GeneType::modifier(|_|{None})),
|
Gene::new("Sunflower","head", GeneType::modifier(|_|{Flow::empty()})),
|
||||||
Gene::new("Sunflower","face", GeneType::consumer(|_|{})),
|
Gene::new("Sunflower","face", GeneType::consumer(|_|{})),
|
||||||
], vec![
|
], vec![
|
||||||
(0,1),
|
(0,1),
|
||||||
|
|
@ -30,7 +30,7 @@ pub fn sunflower_template() -> Genome {
|
||||||
|
|
||||||
pub fn cherry_bomb_template() -> Genome {
|
pub fn cherry_bomb_template() -> Genome {
|
||||||
Genome::from_edges(vec![
|
Genome::from_edges(vec![
|
||||||
Gene::new("Cherry bomb","root", GeneType::modifier(|_|{None})),
|
Gene::new("Cherry bomb","root", GeneType::modifier(|_|{Flow::empty()})),
|
||||||
Gene::new("Cherry bomb","head", GeneType::consumer(|_|{})),
|
Gene::new("Cherry bomb","head", GeneType::consumer(|_|{})),
|
||||||
Gene::new("Cherry bomb","head", GeneType::consumer(|_|{})),
|
Gene::new("Cherry bomb","head", GeneType::consumer(|_|{})),
|
||||||
Gene::new("Cherry bomb","face", GeneType::Dummy),
|
Gene::new("Cherry bomb","face", GeneType::Dummy),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use crate::genetics::{flow::Flow, gene::{Gene, GeneType}, genome::Genome, manipu
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_display() {
|
fn test_display() {
|
||||||
|
println!("{}",peashooter_template());
|
||||||
assert!(peashooter_template().to_string() == "(Peashooter) root\n\t(Peashooter) stem\n\t\t(Peashooter) head\n\t\t\t(Peashooter) leaf\n\t\t\t(Peashooter) face\n");
|
assert!(peashooter_template().to_string() == "(Peashooter) root\n\t(Peashooter) stem\n\t\t(Peashooter) head\n\t\t\t(Peashooter) leaf\n\t\t\t(Peashooter) face\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9,7 +10,15 @@ fn test_display() {
|
||||||
fn test_allelic_crossingover() {
|
fn test_allelic_crossingover() {
|
||||||
let mut peashooter = peashooter_template();
|
let mut peashooter = peashooter_template();
|
||||||
let mut sunflower = sunflower_template();
|
let mut sunflower = sunflower_template();
|
||||||
PairGenomeModificator::with_seed(&mut peashooter, &mut sunflower,3996684975687038250u64).allelic_crossingover(None);
|
|
||||||
|
println!("Peashooter:\n{}",peashooter);
|
||||||
|
println!("Sunflower:\n{}",sunflower);
|
||||||
|
|
||||||
|
(peashooter,sunflower) = PairGenomeModificator::with_seed(peashooter, sunflower,3996684975687038250u64).allelic_crossingover(None);
|
||||||
|
|
||||||
|
println!("Peashooter:\n{}",peashooter);
|
||||||
|
println!("Sunflower:\n{}",sunflower);
|
||||||
|
|
||||||
assert!(peashooter.to_string() == Genome::from_edges(vec![
|
assert!(peashooter.to_string() == Genome::from_edges(vec![
|
||||||
Gene::new("Sunflower","root", GeneType::Dummy),
|
Gene::new("Sunflower","root", GeneType::Dummy),
|
||||||
Gene::new("Peashooter","stem", GeneType::fill_all()),
|
Gene::new("Peashooter","stem", GeneType::fill_all()),
|
||||||
|
|
@ -22,11 +31,12 @@ fn test_allelic_crossingover() {
|
||||||
(2,3),
|
(2,3),
|
||||||
(2,4)
|
(2,4)
|
||||||
]).unwrap().to_string());
|
]).unwrap().to_string());
|
||||||
|
|
||||||
assert!(sunflower.to_string() == Genome::from_edges(vec![
|
assert!(sunflower.to_string() == Genome::from_edges(vec![
|
||||||
Gene::new("Peashooter","root", GeneType::pure_producer(|_|{Flow::empty()})),
|
Gene::new("Peashooter","root", GeneType::pure_producer(|_|{Flow::empty()})),
|
||||||
Gene::new("Sunflower","stem", GeneType::Dummy),
|
Gene::new("Sunflower","stem", GeneType::Dummy),
|
||||||
Gene::new("Sunflower","head", GeneType::modifier(|_|{None})),
|
Gene::new("Sunflower","head", GeneType::modifier(|_|{Flow::empty()})),
|
||||||
Gene::new("Peashooter","leaf",GeneType::modifier(|_|{None})),
|
Gene::new("Peashooter","leaf",GeneType::modifier(|_|{Flow::empty()})),
|
||||||
], vec![
|
], vec![
|
||||||
(0,1),
|
(0,1),
|
||||||
(1,2),
|
(1,2),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue