/*
* File: CrossoverReproducer.java
* Authors: Justin Basilico and Jonathan McClain
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright May 3, 2006, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.learning.algorithm.genetic.reproducer;
import gov.sandia.cognition.annotation.CodeReview;
import gov.sandia.cognition.annotation.CodeReviews;
import gov.sandia.cognition.learning.algorithm.genetic.EvaluatedGenome;
import gov.sandia.cognition.learning.algorithm.genetic.selector.Selector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* The CrossoverReproducer takes a population of genomes, and applies the
* supplied CrossoverFunction to produce a new population.
*
* @param <GenomeType> Type of genome used to represent a single element in the
* genetic population, such as a Vector, for example
* @author Justin Basilico
* @author Jonathan McClain
* @since 1.0
*/
@CodeReviews(
reviews={
@CodeReview(
reviewer="Kevin R. Dixon",
date="2008-07-23",
changesNeeded=false,
comments={
"This class still has open task from last code review, but I suspect it's due to lack of interest.",
"Moved previous code review to CodeReview annotation",
"Otherwise, looks fine."
}
)
,
@CodeReview(
reviewer="Justin Basilico",
date="2006-10-04",
changesNeeded=false,
comments={
"Class looks fine.",
"It may want to include some randomness in case the selector that it calls is deterministic and returns the same population twice."
}
)
}
)
public class CrossoverReproducer<GenomeType>
extends Object
implements Reproducer<GenomeType>
{
/** The selector to use to select the population. */
private Selector<GenomeType> selector;
/** The crossover function to use. */
private CrossoverFunction<GenomeType> crossoverFunction;
/**
* Creates a new instance of CrossoverReproducer
*
* @param selector The selector for the population to use.
* @param crossoverFunction The crossover function to use.
*/
public CrossoverReproducer(
Selector<GenomeType> selector,
CrossoverFunction<GenomeType> crossoverFunction)
{
super();
this.setSelector(selector);
this.setCrossoverFunction(crossoverFunction);
}
/**
* Produces a new population of genomes from the supplied population using
* crossover. It works by using the selector to select two sets of genomes
* and then crosses them over.
*
* @param genomes The population to reproduce.
* @return The new population.
*/
public ArrayList<GenomeType> reproduce(
Collection<EvaluatedGenome<GenomeType>> genomes)
{
// TO DO: Deal with the problem of having a deterministic selector by using
// permutations to do the actual matching up.
// Select two sets of genomes.
Collection<EvaluatedGenome<GenomeType>> selectedGenomes1 =
this.getSelector().select(genomes);
Collection<EvaluatedGenome<GenomeType>> selectedGenomes2 =
this.getSelector().select(genomes);
// Create the ArrayList of results.
int numGenomes =
Math.min(selectedGenomes1.size(), selectedGenomes2.size());
ArrayList<GenomeType> newGenomes =
new ArrayList<GenomeType>(numGenomes);
// Iterate over both sets of selected genomes.
Iterator<EvaluatedGenome<GenomeType>> it1 = selectedGenomes1.iterator();
Iterator<EvaluatedGenome<GenomeType>> it2 = selectedGenomes2.iterator();
while ( it1.hasNext() && it2.hasNext() )
{
// Perform the crossover between the two genomes.
GenomeType genome1 = it1.next().getGenome();
GenomeType genome2 = it2.next().getGenome();
GenomeType newGenome =
this.getCrossoverFunction().crossover(genome1, genome2);
newGenomes.add(newGenome);
}
return newGenomes;
}
/**
* Gets the selector.
*
* @return The selector.
*/
public Selector<GenomeType> getSelector()
{
return this.selector;
}
/**
* Gets the CrossoverFunction.
*
* @return The CrossoverFunction.
*/
public CrossoverFunction<GenomeType> getCrossoverFunction()
{
return this.crossoverFunction;
}
/**
* Sets the selector.
*
* @param selector The new selector.
*/
public void setSelector(
Selector<GenomeType> selector)
{
this.selector = selector;
}
/**
* Sets the CrossoverFunction.
*
* @param crossoverFunction The new CrossoverFunction.
*/
public void setCrossoverFunction(
CrossoverFunction<GenomeType> crossoverFunction)
{
this.crossoverFunction = crossoverFunction;
}
}