/*
* This file is part of JGAP.
*
* JGAP offers a dual license model containing the LGPL as well as the MPL.
*
* For licensing information please see the file license.txt included with JGAP
* or have a look at the top of class org.jgap.Chromosome which representatively
* includes the JGAP license policy applicable for any file delivered with JGAP.
*/
package org.jgap.impl;
import java.util.*;
import org.jgap.*;
import junit.framework.*;
/**
* Tests the MutationOperator class.
*
* @author Klaus Meffert
* @since 1.1
*/
public class MutationOperatorTest
extends JGAPTestCase {
/** String containing the CVS revision. Read out via reflection!*/
private static final String CVS_REVISION = "$Revision: 1.39 $";
public static Test suite() {
TestSuite suite = new TestSuite(MutationOperatorTest.class);
return suite;
}
public void setUp() {
super.setUp();
Configuration.reset();
}
/**
* @throws Exception
*
* @author Klaus Meffert
*/
public void testConstruct_0()
throws Exception {
MutationOperator mutOp = new MutationOperator(conf, 234);
assertEquals(234, mutOp.getMutationRate());
assertNull(mutOp.getMutationRateCalc());
}
/**
* @throws Exception
*
* @author Klaus Meffert
*/
public void testConstruct_1()
throws Exception {
MutationOperator mutOp = new MutationOperator(conf);
assertEquals(0, mutOp.getMutationRate());
assertNotNull(mutOp.getMutationRateCalc());
}
/**
* @throws Exception
*
* @author Klaus Meffert
*/
public void testConstruct_2()
throws Exception {
MutationOperator mutOp = new MutationOperator(conf, null);
assertEquals(0, mutOp.getMutationRate());
assertNull(mutOp.getMutationRateCalc());
}
/**
* @throws Exception
*
* @author Klaus Meffert
*/
public void testConstruct_3()
throws Exception {
IUniversalRateCalculator calc = new DefaultMutationRateCalculator(conf);
MutationOperator mutOp = new MutationOperator(conf, calc);
assertEquals(0, mutOp.getMutationRate());
assertEquals(calc, mutOp.getMutationRateCalc());
}
/**
* Ensure that size of mutated set of chromosomes equals the size of original
* chromosomes.
* @throws Exception
*
* @author Klaus Meffert
*/
public void testOperate_0()
throws Exception {
Configuration conf = new DefaultConfiguration();
conf.setFitnessFunction(new TestFitnessFunction());
MutationOperator mutOp = new MutationOperator(conf);
List candChroms = new Vector();
Chromosome[] population = new Chromosome[] {};
mutOp.operate(new Population(conf, population), candChroms);
assertEquals(candChroms.size(), population.length);
}
/**
* Ensure that size of mutated set of chromosomes equals the size of original
* chromosomes.
*
* @throws Exception
*
* @author Klaus Meffert
*/
public void testOperate_0_2()
throws Exception {
Configuration conf = new DefaultConfiguration();
conf.setFitnessFunction(new TestFitnessFunction());
MutationOperator mutOp = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
List candChroms = new Vector();
RandomGeneratorForTesting gen = new RandomGeneratorForTesting();
gen.setNextInt(9);
conf.setRandomGenerator(gen);
Chromosome c1 = new Chromosome(conf, new BooleanGene(conf), 9);
conf.setSampleChromosome(c1);
conf.addNaturalSelector(new BestChromosomesSelector(conf), true);
conf.setPopulationSize(5);
for (int i = 0; i < c1.getGenes().length; i++) {
c1.getGene(i).setAllele(Boolean.TRUE);
}
Chromosome c2 = new Chromosome(conf, new IntegerGene(conf), 4);
for (int i = 0; i < c2.getGenes().length; i++) {
c2.getGene(i).setAllele(new Integer(27));
}
Chromosome[] population = new Chromosome[] {
c1, c2};
mutOp.operate(new Population(conf, population), candChroms);
assertEquals(candChroms.size(), population.length);
}
/**
* Mutating with different types of genes contained in the population should
* be possible without exception.
*
* @throws Exception
*
* @author Klaus Meffert
*/
public void testOperate_1()
throws Exception {
List candChroms = new Vector();
Configuration conf = new Configuration();
conf.setPopulationSize(3);
conf.setRandomGenerator(new StockRandomGenerator());
MutationOperator mutOp = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
Chromosome[] population = new Chromosome[] {
new Chromosome(conf, new BooleanGene(conf), 9),
(new Chromosome(conf, new IntegerGene(conf), 4))};
mutOp.operate(new Population(conf, population), candChroms);
}
/**
* NullpointerException because of null Configuration.
* @throws Exception
*
* @author Klaus Meffert
*/
public void testOperate_2()
throws Exception {
MutationOperator mutOp = new MutationOperator(conf);
List candChroms = new Vector();
Chromosome[] population = new Chromosome[] {
new Chromosome(conf, new BooleanGene(conf), 9),
(new Chromosome(conf, new IntegerGene(conf), 4))};
try {
mutOp.operate(new Population(null, population), candChroms);
fail();
} catch (InvalidConfigurationException nex) {
; //this is OK
}
}
/**
* Tests if population size grows expectedly after two consecutive calls.
*
* @throws Exception
*
* @author Klaus Meffert
* @since 2.1
*/
public void testOperate_3()
throws Exception {
DefaultConfiguration conf = new DefaultConfiguration();
MutationOperator op = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
conf.addGeneticOperator(op);
RandomGeneratorForTesting rand = new RandomGeneratorForTesting();
rand.setNextInt(0);
conf.setRandomGenerator(rand);
conf.setFitnessFunction(new TestFitnessFunction());
Gene sampleGene = new IntegerGene(conf, 1, 10);
Chromosome chrom = new Chromosome(conf, sampleGene, 3);
conf.setSampleChromosome(chrom);
conf.setPopulationSize(6);
Gene cgene1 = new IntegerGene(conf, 1, 10);
cgene1.setAllele(new Integer(6));
Gene[] genes1 = new Gene[] {
cgene1};
Chromosome chrom1 = new Chromosome(conf, genes1);
Gene cgene2 = new IntegerGene(conf, 1, 10);
cgene2.setAllele(new Integer(9));
Gene[] genes2 = new Gene[] {
cgene2};
Chromosome chrom2 = new Chromosome(conf, genes2);
Chromosome[] population = new Chromosome[] {
chrom1, chrom2};
List chroms = new Vector();
Gene gene1 = new IntegerGene(conf, 1, 10);
gene1.setAllele(new Integer(5));
chroms.add(gene1);
Gene gene2 = new IntegerGene(conf, 1, 10);
gene2.setAllele(new Integer(7));
chroms.add(gene2);
Gene gene3 = new IntegerGene(conf, 1, 10);
gene3.setAllele(new Integer(4));
chroms.add(gene3);
assertEquals(3, chroms.size());
Population pop = new Population(conf, population);
op.operate(pop, chroms);
assertEquals(2, pop.size());
assertEquals(3 + 2, chroms.size());
op.operate(pop, chroms);
assertEquals(2, pop.size());
assertEquals(3 + 2 + 2, chroms.size());
}
/**
* @throws Exception
*
* @author Dan Clark
* @since 2.6
*/
public void testOperate_3_1()
throws Exception {
DefaultConfiguration conf = new DefaultConfiguration();
GeneticOperator op = new MutationOperator(conf, 10);
conf.addGeneticOperator(op);
RandomGeneratorForTesting rand = new RandomGeneratorForTesting();
// 0 in this sequence represents a gene to be mutated
// thus, the middle gene of each chromosome should be mutated
rand.setNextIntSequence(new int[] {1, 0, 1});
rand.setNextDouble(0.7d);
conf.setRandomGenerator(rand);
conf.setFitnessFunction(new TestFitnessFunction());
Gene sampleGene = new IntegerGene(conf, 0, 9);
Chromosome chrom = new Chromosome(conf, sampleGene, 3);
conf.setSampleChromosome(chrom);
conf.setPopulationSize(6);
Gene[] genes1 = new Gene[3];
for (int i = 0; i < genes1.length; i++) {
genes1[i] = new IntegerGene(conf, 0, 9);
genes1[i].setAllele(new Integer(i));
}
Chromosome chrom1 = new Chromosome(conf, genes1);
Gene[] genes2 = new Gene[3];
for (int i = 0; i < genes2.length; i++) {
genes2[i] = new IntegerGene(conf, 0, 9);
genes2[i].setAllele(new Integer(i + 3));
}
Chromosome chrom2 = new Chromosome(conf, genes2);
Chromosome[] population = new Chromosome[] {
chrom1, chrom2};
// this will cause an increase of 4 in mutated values
// original + (0.7*2 - 1) * 10 (range of allele values)
List chroms = new Vector();
Population pop = new Population(conf, population);
op.operate(pop, chroms);
assertEquals(2, chroms.size());
// test chromosome 1 - 2nd gene should be different
Chromosome c1 = (Chromosome) chroms.get(0);
assertEquals(new Integer(0), c1.getGene(0).getAllele());
assertEquals(new Integer(1 + 4), c1.getGene(1).getAllele());
assertEquals(new Integer(2), c1.getGene(2).getAllele());
// test chromosome 2 - 2nd gene should be different
Chromosome c2 = (Chromosome) chroms.get(1);
assertEquals(new Integer(3), c2.getGene(0).getAllele());
assertEquals(new Integer(4 + 4), c2.getGene(1).getAllele());
assertEquals(new Integer(5), c2.getGene(2).getAllele());
op.operate(pop, chroms);
assertEquals(4, chroms.size());
}
/**
* Ensure that nothing is done.
* @throws Exception
*
* @author Klaus Meffert
* @since 2.4
*/
public void testOperate_4()
throws Exception {
DefaultConfiguration conf = new DefaultConfiguration();
MutationOperator mutOp = new MutationOperator(conf, 0);
mutOp.setMutationRateCalc(null);
List candChroms = new Vector();
BooleanGene gene1 = new BooleanGene(conf);
Chromosome chrom1 = new Chromosome(conf, gene1, 1);
chrom1.getGene(0).setAllele(Boolean.valueOf(false));
IntegerGene gene2 = new IntegerGene(conf, 0, 10);
Chromosome chrom2 = new Chromosome(conf, gene2, 1);
chrom2.getGene(0).setAllele(new Integer(3));
candChroms.add(chrom1);
candChroms.add(chrom2);
mutOp.operate(null, candChroms);
assertEquals(2, candChroms.size());
assertEquals(chrom1, candChroms.get(0));
assertEquals(chrom2, candChroms.get(1));
}
/**
* Mutation, especially tested for an IntegerGene.
*
* @throws Exception
*
* @author Klaus Meffert
* @since 2.2
*/
public void testOperate_5()
throws Exception {
Configuration conf = new Configuration();
conf.setPopulationSize(5);
RandomGeneratorForTesting rn = new RandomGeneratorForTesting();
rn.setNextInt(0);
rn.setNextDouble(0.8d); //C
conf.setRandomGenerator(rn);
BooleanGene gene1 = new BooleanGene(conf);
Chromosome chrom1 = new Chromosome(conf, gene1, 1);
chrom1.getGene(0).setAllele(Boolean.valueOf(false));
IntegerGene gene2 = new IntegerGene(conf, 0, 10); //B: B1, B2
Chromosome chrom2 = new Chromosome(conf, gene2, 1);
chrom2.getGene(0).setAllele(new Integer(3)); //A
Chromosome[] chroms = new Chromosome[] {
chrom1, chrom2};
MutationOperator mutOp = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
Population pop = new Population(conf, chroms);
mutOp.operate(pop, pop.getChromosomes());
// now we should have the double number of chromosomes because the target
// list is the same as the source list of chromosomes
assertEquals(2 + 2, pop.getChromosomes().size());
//old gene
assertFalse( ( (BooleanGene) pop.getChromosome(0).getGene(0))
.booleanValue());
//mutated gene
assertTrue( ( (BooleanGene) pop.getChromosome(2).getGene(0)).booleanValue());
//old gene
assertEquals(3, ( (IntegerGene) pop.getChromosome(1).getGene(0)).intValue());
//mutated gene: A + (B2-B1) * (-1 + C * 2) --> see IntegerGene.applyMutation
// A, B1, B2, C: see comments above
// -1 + C * 2: see IntegerGene.applyMutation
assertEquals( (int) Math.round(3 + (10 - 0) * ( -1 + 0.8d * 2)),
( (IntegerGene) pop.getChromosome(3).getGene(0)).intValue());
}
/**
* Mutation, especially tested for an IntegerGene. Uses a CompositeGene.
*
* @throws Exception
*
* @author Klaus Meffert
* @since 2.2
*/
public void testOperate_5_2()
throws Exception {
Configuration conf = new Configuration();
conf.setPopulationSize(5);
BooleanGene gene1 = new BooleanGene(conf);
CompositeGene comp1 = new CompositeGene(conf);
comp1.addGene(gene1);
Chromosome chrom1 = new Chromosome(conf, comp1, 1);
( (CompositeGene) chrom1.getGene(0)).geneAt(0).setAllele(
Boolean.valueOf(false));
IntegerGene gene2 = new IntegerGene(conf, 0, 10);
CompositeGene comp2 = new CompositeGene(conf);
comp2.addGene(gene2);
Chromosome chrom2 = new Chromosome(conf, comp2, 1);
( (CompositeGene) chrom2.getGene(0)).geneAt(0).setAllele(new Integer(3));
Chromosome[] chroms = new Chromosome[] {
chrom1, chrom2};
MutationOperator mutOp = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
RandomGeneratorForTesting rn = new RandomGeneratorForTesting();
rn.setNextInt(0);
rn.setNextDouble(0.8d);
conf.setRandomGenerator(rn);
Population pop = new Population(conf, chroms);
mutOp.operate(pop, pop.getChromosomes());
assertEquals(2 + 2, pop.getChromosomes().size());
//old gene
assertFalse( ( (BooleanGene) ( (CompositeGene) pop.getChromosome(0).getGene(
0)).geneAt(0)).booleanValue());
//mutated gene
assertTrue( ( (BooleanGene) ( (CompositeGene) pop.getChromosome(2).getGene(
0)).geneAt(0)).booleanValue());
//old gene
assertEquals(3,
( (IntegerGene) ( (CompositeGene) pop.getChromosome(1).
getGene(0)).geneAt(0)).intValue());
//mutated gene: A + (B2-B1) * (-1 + C * 2) --> see IntegerGene.applyMutation
// A, B1, B2, C: see comments above
// -1 + C * 2: see IntegerGene.applyMutation
assertEquals( (int) Math.round(3 + (10 - 0) * ( -1 + 0.8d * 2)),
( (
IntegerGene) ( (CompositeGene) pop.getChromosome(3).
getGene(0)).
geneAt(0)).intValue());
}
/**
* Following should be possible without exception.
* @throws Exception
*
* @author Klaus Meffert
* @since 2.2
*/
public void testOperate_6()
throws Exception {
Configuration conf = new DefaultConfiguration();
MutationOperator mutOp = new MutationOperator(conf, 0);
mutOp.setMutationRateCalc(null);
mutOp.operate(null, null);
}
/**
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void testOperate_6_2()
throws Exception {
Configuration conf = new DefaultConfiguration();
MutationOperator mutOp = new MutationOperator(conf, 0);
mutOp.setMutationRateCalc(new DefaultMutationRateCalculator(conf));
mutOp.operate(null, null);
}
/**
* Considers IGeneticOperatorConstraint. Here, the mutation of a BooleanGene
* is forbidden by that constraint.
*
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void testOperate_8()
throws Exception {
Configuration conf = new Configuration();
conf.setPopulationSize(5);
RandomGeneratorForTesting rn = new RandomGeneratorForTesting();
rn.setNextInt(0);
rn.setNextInt(0);
rn.setNextDouble(0.8d);
conf.setRandomGenerator(rn);
BooleanGene gene1 = new BooleanGene(conf);
Chromosome chrom1 = new Chromosome(conf, gene1, 1);
chrom1.getGene(0).setAllele(Boolean.valueOf(false));
IntegerGene gene2 = new IntegerGene(conf, 0, 10);
Chromosome chrom2 = new Chromosome(conf, gene2, 1);
chrom2.getGene(0).setAllele(new Integer(3));
Chromosome[] chroms = new Chromosome[] {
chrom1, chrom2};
MutationOperator mutOp = new MutationOperator(conf,
new
DefaultMutationRateCalculator(
conf));
IGeneticOperatorConstraint constraint = new
GeneticOperatorConstraintForTesting();
conf.getJGAPFactory().setGeneticOperatorConstraint(
constraint);
Population pop = new Population(conf, chroms);
mutOp.operate(pop, pop.getChromosomes());
// +1 (not +2) because only IntegerGene should have been mutated.
assertEquals(2 + 1, pop.getChromosomes().size());
//old gene
assertFalse( ( (BooleanGene) pop.getChromosome(0).getGene(0)).booleanValue());
//old gene
assertEquals(3, ( (IntegerGene) pop.getChromosome(1).
getGene(0)).intValue());
//mutated gene
assertEquals( (int) Math.round(3 + (10 - 0) * ( -1 + 0.8d * 2)),
( (IntegerGene) pop.getChromosome(2).getGene(0)).intValue());
}
/**
* Ensures operator is implementing Serializable
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void testIsSerializable_0()
throws Exception {
MutationOperator op = new MutationOperator(conf);
assertTrue(isSerializable(op));
}
/**
* Ensures that operator and all objects contained implement Serializable.
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void testDoSerialize_0()
throws Exception {
// construct object to be serialized
IUniversalRateCalculator calc = new DefaultCrossoverRateCalculator(conf);
MutationOperator op = new MutationOperator(conf, calc);
Object o = doSerialize(op);
assertEquals(o, op);
}
public class GeneticOperatorConstraintForTesting
implements IGeneticOperatorConstraint {
public boolean isValid(Population a_pop, List a_chromosomes,
GeneticOperator a_caller) {
Chromosome chrom = (Chromosome) a_chromosomes.get(0);
Gene gene = chrom.getGene(0);
return gene.getClass() != BooleanGene.class;
}
}
/**
* Test equals with classcast object.
*
* @throws Exception
* @author Klaus Meffert
* @since 2.6
*/
public void testEquals_0()
throws Exception {
GeneticOperator op = new MutationOperator(conf);
assertFalse(op.equals(new Chromosome(conf)));
}
/**
* @throws Exception
*
* @author Klaus Meffert
* @since 2.6
*/
public void testCompareTo_0()
throws Exception {
MutationOperator op = new MutationOperator(conf);
assertEquals(1, op.compareTo(null));
MutationOperator op2 = new MutationOperator(conf);
assertEquals(0, op.compareTo(op2));
op = new MutationOperator(conf, 3);
assertEquals( -1, op.compareTo(op2));
assertEquals(1, op2.compareTo(op));
op = new MutationOperator(conf, new DefaultMutationRateCalculator(conf));
assertEquals(0, op.compareTo(op2));
op = new MutationOperator(conf, 3);
op2 = new MutationOperator(conf, 4);
assertEquals( -1, op.compareTo(op2));
assertEquals(1, op2.compareTo(op));
}
}