/*
* File: VectorizableCrossoverFunction.java
* Authors: Jonathan McClain
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright May 4, 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.math.matrix.Vectorizable;
import gov.sandia.cognition.math.matrix.Vector;
import gov.sandia.cognition.util.AbstractRandomized;
import java.util.Random;
/**
* The VectorizableCrossoverFunction class is a {@code CrossoverFunction} that
* takes two {@code Vectorizable}.
*
* @author Justin Basilico
* @author Kevin Dixon
* @author Jonathan McClain
* @since 1.0
*/
@CodeReviews(
reviews={
@CodeReview(
reviewer="Kevin R. Dixon",
date="2008-07-23",
changesNeeded=false,
comments={
"Now extends AbstractRandomized.",
"Moved previous code review as CodeReview annotation",
"Looks fine."
}
)
,
@CodeReview(
reviewer="Justin Basilico",
date="2006-10-04",
changesNeeded=false,
comments={
"Restructured the code to get rid of some extra copying.",
"Added the Random object as part of the constructor instead of creating it each time inside the reproduction loop."
}
)
}
)
public class VectorizableCrossoverFunction
extends AbstractRandomized
implements CrossoverFunction<Vectorizable>
{
/**
* Probability that an element in the child will come from vector2, and
* with probability (1-probabilityCrossover) the element will come from
* vector1. Thus, probabilityCrossover==0.0 means that all elements will
* come from vector1 and probabilityCrossover==1.0 means that all elements
* will come from vector2, probabilityCrossover==0.5 has maximum entropy
* in terms of where the elements of the child vector came from
*/
private double probabilityCrossover;
/**
* Default probability of cross over, {@value}.
*/
public static final double DEFAULT_PROBABILITY = 0.5;
/**
* Creates a new instance of VectorizableCrossoverFunction with an crossover
* probability of 0.5.
*/
public VectorizableCrossoverFunction()
{
this(DEFAULT_PROBABILITY);
}
/**
* Creates a new instance of VectorizableCrossoverFunction.
*
* @param probabilityCrossover Probability that an element in the child
* will come from vector2
*/
public VectorizableCrossoverFunction(
double probabilityCrossover)
{
this(probabilityCrossover, new Random());
}
/**
* Creates a new instance of VectorizableCrossoverFunction.
*
* @param probabilityCrossover Probability that an element in the child
* will come from vector2
* @param random The random number generator to use.
*/
public VectorizableCrossoverFunction(
double probabilityCrossover,
Random random)
{
super( random );
this.setProbabilityCrossover(probabilityCrossover);
}
/**
* Crosses over each element of the parent vectors. Uses a random boolean
* to decide which parent contributes an element to the child.
*
* @param parent1 The first parent to crossover.
* @param parent2 The second parent to crossover.
* @return The result of the crossover.
*/
public Vectorizable crossover(
Vectorizable parent1,
Vectorizable parent2)
{
// Convert to a vector.
Vector vector1 = parent1.convertToVector();
Vector vector2 = parent2.convertToVector();
// Create the child by cloning the first parent and then copying the
// second parent's values in when the probability is correct.
Vector child = vector1.clone();
for (int i = 0; i < child.getDimensionality(); i++)
{
if ( this.random.nextDouble() <= this.getProbabilityCrossover() )
{
child.setElement(i, vector2.getElement(i));
}
}
// Create the result of the crossover.
Vectorizable result = parent1.clone();
result.convertFromVector(child);
return result;
}
/**
* Getter for probabilityCrossover.
*
* @return Probability that an element in the child will come from vector2
*/
public double getProbabilityCrossover()
{
return this.probabilityCrossover;
}
/**
* Setter for probabilityCrossover.
*
* @param probabilityCrossover Probability that an element in the child
* will come from vector2
*/
public void setProbabilityCrossover(
double probabilityCrossover)
{
this.probabilityCrossover = probabilityCrossover;
}
}