/*
* File: GeneticAlgorithmTest.java
* Authors: Jonathan McClain
* Company: Sandia National Laboratories
* Project: Cognitive Framework Lite
*
* 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;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.CrossoverReproducer;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.MultiReproducer;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.MutationReproducer;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.Reproducer;
import gov.sandia.cognition.learning.algorithm.genetic.selector.TournamentSelector;
import gov.sandia.cognition.learning.algorithm.genetic.reproducer.VectorizableCrossoverFunction;
import gov.sandia.cognition.learning.function.cost.CostFunction;
import gov.sandia.cognition.learning.function.cost.EuclideanDistanceCostFunction;
import gov.sandia.cognition.math.matrix.Vectorizable;
import gov.sandia.cognition.learning.algorithm.annealing.VectorizablePerturber;
import gov.sandia.cognition.math.matrix.VectorFactory;
import gov.sandia.cognition.math.matrix.Matrix;
import gov.sandia.cognition.math.matrix.MatrixFactory;
import gov.sandia.cognition.math.matrix.Vector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Random;
import junit.framework.*;
/**
* This class implements JUnit tests for the following classes
*
* GeneticAlgorithm
*
* @author Jonathan McClain
* @since 1.0
*/
public class GeneticAlgorithmTest extends TestCase
{
// /** The genetic algorithm to use in the tests. */
// protected GeneticAlgorithm<Vectorizable, Vectorizable> ga;
/** The cost function to use in the tests. */
protected EuclideanDistanceCostFunction cost;
/** The size of the population for the tests. */
private int populationSize;
/** The size of the vectors to be used in the tests. */
private int vectorSize;
/** The goal of the tests. */
private Vector goal;
/** The percent of the population to carry over using the tournament selector. */
private double carryOverPercent;
/** The percent of the population to crossover. */
private double crossoverPercent;
/** The percent of the population to mutate. */
private double mutatePercent;
/** The random number generator for the tests. */
private Random random = new Random();
/** Initial population to use in creating a new ga instance */
protected ArrayList<Vectorizable> initialPopulation;
/** Reproducer to use in creating a new ga instance */
protected MultiReproducer<Vectorizable> multiReproducer;
/**
* Creates a new instance of GeneticAlgorithmTest.
*/
public GeneticAlgorithmTest(String testName)
{
super(testName);
this.setPopulationSize(100);
this.setVectorSize(2);
this.setCarryOverPercent(0.1);
this.setCrossoverPercent(0.4);
this.setMutatePercent(0.5);
double range = 2;
// Create the goal
Vector goalVector = VectorFactory.getDefault().createUniformRandom(this.getVectorSize(), -range, range, random);
this.setGoal(goalVector.clone());
System.out.print("Goal = ");
for(int i = 0;
i < this.getGoal().convertToVector().getDimensionality();
i++)
{
double num = this.getGoal().convertToVector().getElement(i);
System.out.print(num);
System.out.print(" ");
}
System.out.println("");
this.setCost(new EuclideanDistanceCostFunction(goal));
Matrix covariance = MatrixFactory.getDefault().createIdentity(
this.getVectorSize(), this.getVectorSize()).scale( 1e-6 );
// Prepare the reproducers
TournamentSelector<Vectorizable> bestSelector =
new TournamentSelector<Vectorizable>(this.getCarryOverPercent(), 10);
TournamentSelector<Vectorizable> mutationSelector =
new TournamentSelector<Vectorizable>(this.getMutatePercent(), 10);
TournamentSelector<Vectorizable> crossoverSelector =
new TournamentSelector<Vectorizable>(this.getCrossoverPercent(), 10);
VectorizablePerturber perturber =
new VectorizablePerturber(new Random(), covariance);
MutationReproducer<Vectorizable> mutationReproducer =
new MutationReproducer<Vectorizable>(
perturber,
mutationSelector);
double probabilityCrossover = 0.5;
VectorizableCrossoverFunction crossoverFunction =
new VectorizableCrossoverFunction( probabilityCrossover );
CrossoverReproducer<Vectorizable> crossoverReproducer =
new CrossoverReproducer<Vectorizable>(
crossoverSelector, crossoverFunction);
ArrayList<Reproducer<Vectorizable>> reproducers =
new ArrayList<Reproducer<Vectorizable>>();
reproducers.add(bestSelector);
reproducers.add(crossoverReproducer);
reproducers.add(mutationReproducer);
this.multiReproducer =
new MultiReproducer<Vectorizable>(reproducers);
// Create the random population
this.initialPopulation = createPopulation(this.populationSize, range);
}
protected ArrayList<Vectorizable> createPopulation( int size, double range )
{
ArrayList<Vectorizable> population = new ArrayList<Vectorizable>(size);
for(int i = 0; i < size; i++)
{
Vector initialVector = VectorFactory.getDefault().createUniformRandom(this.getVectorSize(), -range, range, random);
Vector initial = initialVector.clone();
population.add(initial);
}
return population;
}
/**
* Creates a default instance of GeneticAlgorithm.
*
* @return Returns a new default instance.
*/
public GeneticAlgorithm<Vectorizable, Vectorizable> createInstance()
{
return new GeneticAlgorithm<Vectorizable, Vectorizable>(
this.initialPopulation, this.multiReproducer, this.getCost());
}
/**
* Test of minimize method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testMinimize() {
System.out.println("minimize");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
// Minimize on the population.
ga.learn(this.getCost().getCostParameters());
EvaluatedGenome<Vectorizable> result = ga.getBestSoFar();
System.out.print("Result = ");
for(int i = 0;
i < result.getGenome().convertToVector().getDimensionality();
i++)
{
double num = result.getGenome().convertToVector().getElement(i);
System.out.print(num);
System.out.print(" ");
}
System.out.println("");
System.out.println("Result cost = " + result.getCost());
assertEquals(result.getCost(), 0, .01);
}
/**
* Test of searchForBetter method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testSearchForBetter()
{
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
EvaluatedGenome<Vectorizable> bestSoFar =
new EvaluatedGenome<Vectorizable>(0.0, VectorFactory.getDefault().createVector(3));
EvaluatedGenome<Vectorizable> better =
new EvaluatedGenome<Vectorizable>(-1.0, VectorFactory.getDefault().createVector(3));
EvaluatedGenome<Vectorizable> worse =
new EvaluatedGenome<Vectorizable>(1.0, VectorFactory.getDefault().createVector(3));
LinkedList<EvaluatedGenome<Vectorizable>> population =
new LinkedList<EvaluatedGenome<Vectorizable>>();
population.add(worse);
assertSame(bestSoFar, ga.searchForBetter(bestSoFar, population));
population.add(bestSoFar);
population.add(better);
assertSame(better, ga.searchForBetter(bestSoFar, population));
}
/**
* Test of evaluatePopulation method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testEvaluatePopulation()
{
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
LinkedList<Vectorizable> population = new LinkedList<Vectorizable>();
Vector member = VectorFactory.getDefault().createVector(this.getVectorSize());
population.add(member);
ArrayList<EvaluatedGenome<Vectorizable>> result =
ga.evaluatePopulation(population);
assertNotNull(result);
assertEquals(1, result.size());
assertSame(member, result.get(0).getGenome());
}
/**
* Test of getCost method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetCost() {
System.out.println("getCost");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
EuclideanDistanceCostFunction expected = null;
ga.setCostFunction(expected);
CostFunction<?,?> actual = ga.getCostFunction();
assertEquals(
"getCost did not return the expected CostFunction",
expected,
actual);
}
/**
* Test of getReproducer method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetReproducer() {
System.out.println("getReproducer");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
Reproducer<Vectorizable> expected = null;
ga.setReproducer(expected);
Reproducer<Vectorizable> actual = ga.getReproducer();
assertEquals(
"getReproducer did not return the expected Reproducer",
expected,
actual);
}
/**
* Test of getBestSoFar method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetBestSoFar() {
System.out.println("getBestSoFar");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
EvaluatedGenome<Vectorizable> expected = null;
ga.setBestSoFar(expected);
EvaluatedGenome<Vectorizable> actual = ga.getBestSoFar();
assertEquals(
"getBestSoFar did not return the expected EvaluatedGenome",
expected,
actual);
}
/**
* Test of getMaxIterations method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetMaxIterations() {
System.out.println("getMaxIterations");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 1;
ga.setMaxIterations(expected);
int actual = ga.getMaxIterations();
assertEquals(
"getMaxIterations did not return the expected integer",
expected,
actual);
}
/**
* Test of getIteration method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetIteration() {
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int actual = ga.getIteration();
assertTrue(actual >= 0);
}
/**
* Test of getMaxIterationsWithoutImprovement method, of
* class gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetMaxIterationsWithoutImprovement() {
System.out.println("getMaxIterationsWithoutImprovement");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 0;
ga.setMaxIterationsWithoutImprovement(expected);
int actual = ga.getMaxIterationsWithoutImprovement();
assertEquals(
"getMaxIterationsWithoutImprovement did not return the expected integer",
expected,
actual);
}
/**
* Test of getIterationsWithoutImprovement method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetIterationsWithoutImprovement() {
System.out.println("getIterationsWithoutImprovement");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 0;
ga.setIterationsWithoutImprovement(expected);
int actual = ga.getIterationsWithoutImprovement();
assertEquals(
"getIterationsWithoutImprovement did not return the expected integer",
expected,
actual);
}
/**
* Test of getPopulation method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testGetPopulation() {
System.out.println("getPopulation");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
Collection<EvaluatedGenome<Vectorizable>> expected = null;
ga.setPopulation(expected);
Collection<EvaluatedGenome<Vectorizable>> actual = ga.getPopulation();
assertEquals(
"getPopulation did not return the expected population",
expected,
actual);
}
/**
* Test of setCost method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetCost() {
System.out.println("setCost");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
EuclideanDistanceCostFunction expected = null;
ga.setCostFunction(expected);
CostFunction<?,?> actual = ga.getCostFunction();
assertEquals(
"setCost did not set the expected CostFunction",
expected,
actual);
}
/**
* Test of setReproducer method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetReproducer() {
System.out.println("setReproducer");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
Reproducer<Vectorizable> expected = null;
ga.setReproducer(expected);
Reproducer<Vectorizable> actual = ga.getReproducer();
assertEquals(
"setReproducer did not set the expected Reproducer",
expected,
actual);
}
/**
* Test of setBestSoFar method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetBestSoFar() {
System.out.println("setBestSoFar");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
EvaluatedGenome<Vectorizable> expected = null;
ga.setBestSoFar(expected);
EvaluatedGenome<Vectorizable> actual = ga.getBestSoFar();
assertEquals(
"setBestSoFar did not set the expected EvaluatedGenome",
expected,
actual);
}
/**
* Test of setMaxIterations method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetMaxIterations() {
System.out.println("setMaxIterations");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 1;
ga.setMaxIterations(expected);
int actual = ga.getMaxIterations();
assertEquals(
"setMaxIterations did not set the expected integer",
expected,
actual);
}
/**
* Test of setMaxIterationsWithoutImprovement method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetMaxIterationsWithoutImprovement() {
System.out.println("setMaxIterationsWithoutImprovement");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 0;
ga.setMaxIterationsWithoutImprovement(expected);
int actual = ga.getMaxIterationsWithoutImprovement();
assertEquals(
"setMaxIterationsWithoutImprovement did not set the expected integer",
expected,
actual);
}
/**
* Test of setIterationsWithoutImprovement method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetIterationsWithoutImprovement() {
System.out.println("setIterationsWithoutImprovement");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
int expected = 0;
ga.setIterationsWithoutImprovement(expected);
int actual = ga.getIterationsWithoutImprovement();
assertEquals(
"setIterationsWithoutImprovement did not set the expected integer",
expected,
actual);
}
/**
* Test of setPopulation method, of class
* gov.sandia.isrc.learning.reinforcement.GeneticAlgorithm.
*/
public void testSetPopulation() {
System.out.println("setPopulation");
GeneticAlgorithm<Vectorizable, Vectorizable> ga =
this.createInstance();
Collection<EvaluatedGenome<Vectorizable>> expected = null;
ga.setPopulation(expected);
Collection<EvaluatedGenome<Vectorizable>> actual = ga.getPopulation();
assertEquals(
"setPopulation did not set the expected population",
expected,
actual);
}
/**
* Gets the cost function to use in the tests.
*
* @return The cost function.
*/
protected EuclideanDistanceCostFunction getCost()
{
return this.cost;
}
/**
* Gets the size of the vectors to be used in the tests.
*
* @return The vector size.
*/
private int getVectorSize()
{
return this.vectorSize;
}
/**
* Gets the goal of the tests.
*
* @return The goal.
*/
private Vector getGoal()
{
return this.goal;
}
/**
* Gets the percent of the population to carry over using the tournament selector.
*
* @return The percent.
*/
private double getCarryOverPercent()
{
return this.carryOverPercent;
}
/**
* Gets the percent of the population to crossover.
*
* @return The percent.
*/
private double getCrossoverPercent()
{
return this.crossoverPercent;
}
/**
* Gets the percent of the population to mutate.
*
* @return The percent.
*/
private double getMutatePercent()
{
return this.mutatePercent;
}
/**
* Sets the cost function to use in the tests.
*
* @param cost The new cost function.
*/
private void setCost(EuclideanDistanceCostFunction cost)
{
this.cost = cost;
}
/**
* Sets the size of the population for the tests.
*
* @param populationSize The new population size.
*/
private void setPopulationSize(int populationSize)
{
this.populationSize = populationSize;
}
/**
* Sets the size of the vectors to be used in the tests.
*
* @param vectorSize The new vector size.
*/
private void setVectorSize(int vectorSize)
{
this.vectorSize = vectorSize;
}
/**
* Sets the goal of the tests.
*
* @param goal The new goal.
*/
private void setGoal(Vector goal)
{
this.goal = goal;
}
/**
* Sets the percent of the population to carry over using the tournament selector.
*
* @param carryOverPercent The new percent.
*/
private void setCarryOverPercent(double carryOverPercent)
{
this.carryOverPercent = carryOverPercent;
}
/**
* Sets the percent of the population to crossover.
*
* @param crossoverPercent The new percent.
*/
private void setCrossoverPercent(double crossoverPercent)
{
this.crossoverPercent = crossoverPercent;
}
/**
* Sets the percent of the population to mutate.
*
* @param mutatePercent The new percent.
*/
private void setMutatePercent(double mutatePercent)
{
this.mutatePercent = mutatePercent;
}
/**
* Test of getCostFunction method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testGetCostFunction()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertSame(this.cost, instance.getCostFunction());
}
/**
* Test of setCostFunction method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testSetCostFunction()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertSame(this.cost, instance.getCostFunction());
instance.setCostFunction(null);
assertNull(instance.getCostFunction());
}
/**
* Test of getInitialPopulation method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testGetInitialPopulation()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertSame(this.initialPopulation, instance.getInitialPopulation());
}
/**
* Test of setInitialPopulation method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testSetInitialPopulation()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertSame(this.initialPopulation, instance.getInitialPopulation());
Collection<Vectorizable> population = new LinkedList<Vectorizable>();
instance.setInitialPopulation(population);
assertSame(population, instance.getInitialPopulation());
}
/**
* Test of getKeepGoing method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testGetKeepGoing()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertFalse(instance.getKeepGoing());
}
/**
* Test of setKeepGoing method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testSetKeepGoing()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertFalse(instance.getKeepGoing());
instance.setKeepGoing(false);
assertFalse(instance.getKeepGoing());
instance.setKeepGoing(false);
assertFalse(instance.getKeepGoing());
instance.setKeepGoing(true);
assertTrue(instance.getKeepGoing());
}
/**
* Test of isResultValid method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testIsResultValid()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
assertFalse(instance.isResultValid());
instance.setBestSoFar(
new EvaluatedGenome<Vectorizable>(0.0, VectorFactory.getDefault().createVector(3)));
assertTrue(instance.isResultValid());
}
/**
* Test of stop method, of class gov.sandia.isrc.learning.genetic.GeneticAlgorithm.
*/
public void testStop()
{
GeneticAlgorithm<Vectorizable, Vectorizable> instance =
this.createInstance();
instance.setKeepGoing(true);
instance.stop();
assertFalse(instance.getKeepGoing());
}
}