Skip to content

Commit

Permalink
Pass GAMetadata to crossover
Browse files Browse the repository at this point in the history
  • Loading branch information
kkafar committed Mar 28, 2024
1 parent 7ead73c commit 14c8c4c
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/ga.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ where
// FIXME: Do not assume that population size is an even number.
self.timer.start();
for parents in mating_pool.chunks(2) {
let crt_children = self.config.crossover_operator.apply(parents[0], parents[1]);
let crt_children = self.config.crossover_operator.apply(&self.metadata, parents[0], parents[1]);

children.push(crt_children.0);
children.push(crt_children.1);
Expand Down
31 changes: 16 additions & 15 deletions src/ga/operators/crossover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::collections::{HashMap, HashSet};
use std::hash::Hash;
use std::ops::{Index, IndexMut};

use crate::ga::GAMetadata;
use crate::ga::individual::{Chromosome, IndividualTrait};
use push_trait::{Nothing, Push};
use rand::prelude::SliceRandom;
Expand All @@ -20,7 +21,7 @@ pub trait CrossoverOperator<IndividualT: IndividualTrait> {
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT);
fn apply(&mut self, metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT);
}

/// # Single point crossover operator
Expand Down Expand Up @@ -69,7 +70,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
let chromosome_len = parent_1.chromosome().len();
let cut_point = self.rng.gen_range(0..chromosome_len);

Expand Down Expand Up @@ -136,7 +137,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -238,7 +239,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -324,7 +325,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -402,7 +403,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -534,7 +535,7 @@ where
///
/// * `parent_1` - First parent to take part in crossover
/// * `parent_2` - Second parent to take part in crossover
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -656,7 +657,7 @@ where
///
/// * `parent_1` - one of the parents to take part in crossover
/// * `parent_2` - one of the parents to take part in crossover
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -819,7 +820,7 @@ where
///
/// * `parent_1` - First parent to take part in crossover
/// * `parent_2` - Second parent to take part in crossover
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
assert_eq!(
parent_1.chromosome().len(),
parent_2.chromosome().len(),
Expand Down Expand Up @@ -888,7 +889,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
let chromosome_len = parent_1.chromosome().len();
let cut_point = self.rng.gen_range(0..chromosome_len);

Expand Down Expand Up @@ -947,7 +948,7 @@ where
///
/// * `parent_1` - First parent to take part in recombination
/// * `parent_2` - Second parent to take part in recombination
fn apply(&mut self, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
fn apply(&mut self, _metadata: &GAMetadata, parent_1: &IndividualT, parent_2: &IndividualT) -> (IndividualT, IndividualT) {
let mut child_1 = parent_1.clone();
let mut child_2 = parent_2.clone();

Expand All @@ -965,7 +966,7 @@ mod test {
use crate::ga::individual::IndividualTrait;
use crate::ga::operators::crossover::Ppx;
use crate::ga::operators::crossover::{CrossoverOperator, FixedPoint, Pmx, Shuffle};
use crate::ga::Individual;
use crate::ga::{Individual, GAMetadata};
use std::iter::zip;

#[test]
Expand Down Expand Up @@ -1005,7 +1006,7 @@ mod test {
let p1 = Individual::from(vec![8, 4, 7, 3, 6, 2, 5, 1, 9, 0]);
let p2 = Individual::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

let (child_1, child_2) = op.apply(&p1, &p2);
let (child_1, child_2) = op.apply(&GAMetadata::default(), &p1, &p2);
assert_eq!(child_1.chromosome.len(), 10);
assert_eq!(child_2.chromosome.len(), 10);
}
Expand All @@ -1017,7 +1018,7 @@ mod test {
let p1 = Individual::from(vec![1, 0, 0, 1, 0, 1, 0, 1, 0, 0]);
let p2 = Individual::from(vec![0, 1, 1, 0, 1, 0, 1, 0, 1, 1]);

let (c1, c2) = op.apply(&p1, &p2);
let (c1, c2) = op.apply(&GAMetadata::default(), &p1, &p2);
for (g1, g2) in c1.chromosome.iter().zip(c2.chromosome.iter()) {
assert_eq!(g1 * g2, 0);
assert_eq!(g1 + g2, 1);
Expand All @@ -1034,7 +1035,7 @@ mod test {
let p1 = Individual::from(parent_1_chromosome.clone());
let p2 = Individual::from(parent_2_chromosome.clone());

let (child_1, child_2) = op.apply(&p1, &p2);
let (child_1, child_2) = op.apply(&GAMetadata::default(), &p1, &p2);

let child_1_expected_chromosome = vec![8, 4, 7, 3, 4, 5, 6, 7, 8, 9];
let child_2_expected_chromosome = vec![0, 1, 2, 3, 6, 2, 5, 1, 9, 0];
Expand Down
5 changes: 3 additions & 2 deletions tests/crossover_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg(feature = "ga")]

use ecrs::ga::GAMetadata;
use ecrs::ga::individual::{IndividualTrait, RealValueIndividual};
use ecrs::ga::operators::crossover::Ppx;
use ecrs::ga::{
Expand All @@ -13,7 +14,7 @@ fn operator_takes_values_from_parents<T: CrossoverOperator<RealValueIndividual>>
let parents = RandomPoints::new(30).generate(2);
assert_eq!(parents.len(), 2, "Expected population of size 2");

let (child_1, child_2) = operator.apply(&parents[0], &parents[1]);
let (child_1, child_2) = operator.apply(&GAMetadata::default(), &parents[0], &parents[1]);
for (i, (gene_1, gene_2)) in std::iter::zip(child_1.chromosome(), child_2.chromosome()).enumerate() {
assert!(parents[0].chromosome()[i] == *gene_1 || parents[1].chromosome()[i] == *gene_1);
assert!(parents[0].chromosome()[i] == *gene_2 || parents[1].chromosome()[i] == *gene_2);
Expand Down Expand Up @@ -49,7 +50,7 @@ fn ppx_test() {

let p1 = Individual::from((0..10).collect_vec());
let p2 = Individual::from((0..10).rev().collect_vec());
let (c1, c2) = op.apply(&p1, &p2);
let (c1, c2) = op.apply(&GAMetadata::default(), &p1, &p2);

c1.chromosome
.iter()
Expand Down

0 comments on commit 14c8c4c

Please sign in to comment.