/**
* Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
*/
package org.evosuite.ga.metaheuristics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.evosuite.Properties;
import org.evosuite.Properties.StoppingCondition;
import org.evosuite.coverage.branch.BranchCoverageSuiteFitness;
import org.evosuite.coverage.line.LineCoverageSuiteFitness;
import org.evosuite.ga.Chromosome;
import org.evosuite.ga.ChromosomeFactory;
import org.evosuite.ga.FitnessFunction;
import org.evosuite.ga.operators.crossover.SBXCrossover;
import org.evosuite.ga.operators.selection.BinaryTournamentSelectionCrowdedComparison;
import org.evosuite.ga.problems.Problem;
import org.evosuite.ga.problems.metrics.GenerationalDistance;
import org.evosuite.ga.problems.metrics.Metrics;
import org.evosuite.ga.problems.metrics.Spacing;
import org.evosuite.ga.problems.multiobjective.ZDT4;
import org.evosuite.testsuite.TestSuiteChromosome;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Unit tests for SPEA2's functions.
*
* @author José Campos
*/
public class SPEA2Test {
@Test
public void testEnvironmentalSelection_FitArchive() {
List<Chromosome> population = new ArrayList<Chromosome>();
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setDistance(0.0);
population.add(t1);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setDistance(0.1);
population.add(t2);
TestSuiteChromosome t3 = new TestSuiteChromosome();
t3.setDistance(0.2);
population.add(t3);
Properties.POPULATION = 3;
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
List<Chromosome> archive = algorithm.environmentalSelection(population);
assertEquals(3, archive.size());
assertEquals(0.0, archive.get(0).getDistance(), 0.0);
assertEquals(0.1, archive.get(1).getDistance(), 0.0);
assertEquals(0.2, archive.get(2).getDistance(), 0.0);
}
@Test
public void testEnvironmentalSelection_SmallArchive() {
List<Chromosome> population = new ArrayList<Chromosome>();
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setDistance(0.0);
population.add(t1);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setDistance(0.1);
population.add(t2);
TestSuiteChromosome t3 = new TestSuiteChromosome();
t3.setDistance(0.2);
population.add(t3);
Properties.POPULATION = 5;
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
List<Chromosome> archive = algorithm.environmentalSelection(population);
assertEquals(3, archive.size());
population.clear();
population.add(t1);
population.add(t2);
population.add(t3);
TestSuiteChromosome t4 = new TestSuiteChromosome();
t4.setDistance(1.0);
population.add(t4);
TestSuiteChromosome t5 = new TestSuiteChromosome();
t5.setDistance(1.0);
population.add(t5);
archive = algorithm.environmentalSelection(population);
assertEquals(5, archive.size());
}
@Test
public void testEnvironmentalSelection_ArchiveTruncation() {
List<Chromosome> population = new ArrayList<Chromosome>();
BranchCoverageSuiteFitness branch = new BranchCoverageSuiteFitness();
LineCoverageSuiteFitness line = new LineCoverageSuiteFitness();
// fill population with good solutions
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setFitness(branch, 0.0);
t1.setFitness(line, 0.0);
population.add(t1);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setFitness(branch, 0.01);
t2.setFitness(line, 0.1);
population.add(t2);
TestSuiteChromosome t3 = new TestSuiteChromosome();
t3.setFitness(branch, 0.5);
t3.setFitness(line, 0.5);
population.add(t3);
TestSuiteChromosome t4 = new TestSuiteChromosome();
t4.setFitness(branch, 0.75);
t4.setFitness(line, 0.5);
population.add(t4);
TestSuiteChromosome t5 = new TestSuiteChromosome();
t5.setFitness(branch, 0.75);
t5.setFitness(line, 0.5);
population.add(t5);
TestSuiteChromosome t6 = new TestSuiteChromosome();
t6.setFitness(branch, 0.80);
t6.setFitness(line, 0.80);
population.add(t6);
Properties.POPULATION = 3; // max number of solutions
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
List<Chromosome> archive = algorithm.environmentalSelection(population);
assertEquals(3, archive.size());
assertTrue(t1.equals(archive.get(0)));
assertTrue(t3.equals(archive.get(1)));
assertTrue(t6.equals(archive.get(2)));
}
@Test
public void testComputeStrength() {
List<Chromosome> population = new ArrayList<Chromosome>();
BranchCoverageSuiteFitness branch = new BranchCoverageSuiteFitness();
LineCoverageSuiteFitness line = new LineCoverageSuiteFitness();
// dominates all the other two chromosomes
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setFitness(branch, 0.0);
t1.setFitness(line, 0.0);
population.add(t1);
// t2 only dominates t3
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setFitness(branch, 0.5);
t2.setFitness(line, 0.5);
population.add(t2);
// t3 is dominated by all chromosomes
TestSuiteChromosome t3 = new TestSuiteChromosome();
t3.setFitness(branch, 1.0);
t3.setFitness(line, 1.0);
population.add(t3);
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
algorithm.computeStrength(population);
assertEquals(0.36, t1.getDistance(), 0.01);
assertEquals(2.36, t2.getDistance(), 0.01);
assertEquals(3.36, t3.getDistance(), 0.01);
// invert order of chromosomes
population.clear();
population.add(t3);
population.add(t2);
population.add(t1);
algorithm.computeStrength(population);
assertEquals(0.36, t1.getDistance(), 0.01);
assertEquals(2.36, t2.getDistance(), 0.01);
assertEquals(3.36, t3.getDistance(), 0.01);
}
@Test
public void testEuclideanDistanceMatrix_EmptyPopulation() {
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
double[][] matrix = algorithm.euclideanDistanceMatrix(new ArrayList<Chromosome>());
assertEquals(0, matrix.length);
}
@Test
public void testEuclideanDistanceMatrix() {
List<Chromosome> population = new ArrayList<Chromosome>();
BranchCoverageSuiteFitness branch = new BranchCoverageSuiteFitness();
LineCoverageSuiteFitness line = new LineCoverageSuiteFitness();
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setFitness(branch, 0.5);
t1.setFitness(line, 0.3);
population.add(t1);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setFitness(branch, 0.3);
t2.setFitness(line, 0.5);
population.add(t2);
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
double[][] matrix = algorithm.euclideanDistanceMatrix(population);
assertEquals(2, matrix.length);
assertEquals(2, matrix[0].length);
assertEquals(2, matrix[1].length);
assertEquals(0.0, matrix[0][0], 0.0);
assertEquals(0.0, matrix[1][1], 0.0);
assertEquals(0.28, matrix[0][1], 0.01);
assertEquals(0.28, matrix[1][0], 0.01);
}
@Test
public void testDistanceOfEqualChromosomes() {
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
BranchCoverageSuiteFitness branch = new BranchCoverageSuiteFitness();
LineCoverageSuiteFitness line = new LineCoverageSuiteFitness();
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setFitness(branch, 0.5);
t1.setFitness(line, 0.3);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setFitness(branch, 0.5);
t2.setFitness(line, 0.3);
assertEquals(0.0, algorithm.distanceBetweenObjectives(t1, t2), 0.0);
}
@Test
public void testDistanceOfDifferentChromosomes() {
SPEA2<Chromosome> algorithm = new SPEA2<Chromosome>(null);
BranchCoverageSuiteFitness branch = new BranchCoverageSuiteFitness();
LineCoverageSuiteFitness line = new LineCoverageSuiteFitness();
TestSuiteChromosome t1 = new TestSuiteChromosome();
t1.setFitness(branch, 0.5);
t1.setFitness(line, 0.3);
TestSuiteChromosome t2 = new TestSuiteChromosome();
t2.setFitness(branch, 0.3);
t2.setFitness(line, 0.5);
assertEquals(0.28, algorithm.distanceBetweenObjectives(t1, t2), 0.01);
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Test
public void testZDT4() throws IOException {
Properties.MUTATION_RATE = 1d / 10d;
Properties.POPULATION = 100;
Properties.SEARCH_BUDGET = 250;
Properties.STOPPING_CONDITION = StoppingCondition.MAXGENERATIONS;
Properties.CROSSOVER_RATE = 0.9;
Properties.RANDOM_SEED = 1l;
ChromosomeFactory<?> factory = new RandomFactory(true, 10, -5.0, 5.0);
GeneticAlgorithm<?> ga = new SPEA2(factory);
BinaryTournamentSelectionCrowdedComparison ts =
new BinaryTournamentSelectionCrowdedComparison();
ts.setMaximize(false);
ga.setSelectionFunction(ts);
ga.setCrossOverFunction(new SBXCrossover());
Problem p = new ZDT4();
final FitnessFunction f1 = (FitnessFunction) p.getFitnessFunctions().get(0);
final FitnessFunction f2 = (FitnessFunction) p.getFitnessFunctions().get(1);
ga.addFitnessFunction(f1);
ga.addFitnessFunction(f2);
// execute
ga.generateSolution();
List<Chromosome> chromosomes = (List<Chromosome>) ga.getPopulation();
Collections.sort(chromosomes, new Comparator<Chromosome>() {
@Override
public int compare(Chromosome arg0, Chromosome arg1) {
return Double.compare(arg0.getFitness(f1), arg1.getFitness(f1));
}
});
double[][] front = new double[Properties.POPULATION][2];
for (int i = 0; i < chromosomes.size(); i++) {
Chromosome chromosome = chromosomes.get(i);
System.out.printf("%f,%f\n", chromosome.getFitness(f1), chromosome.getFitness(f2));
front[i][0] = Double.valueOf(chromosome.getFitness(f1));
front[i][1] = Double.valueOf(chromosome.getFitness(f2));
}
// load True Pareto Front
double[][] trueParetoFront = Metrics.readFront("ZDT4.pf");
GenerationalDistance gd = new GenerationalDistance();
double gdd = gd.evaluate(front, trueParetoFront);
System.out.println("GenerationalDistance: " + gdd);
assertEquals(0.00, gdd, 0.01);
Spacing sp = new Spacing();
double spd = sp.evaluate(front);
System.out.println("SpacingFront: " + spd);
assertEquals(0.71, spd, 0.01);
}
}