/*
Copyright 2006 by Sean Luke
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package ec.vector.breed;
import ec.vector.*;
import ec.*;
import ec.util.Parameter;
/*
* MultipleVectorCrossoverPipeline.java
*
* Created: Thu May 14 2009
* By: Beenish Jamil
*/
/**
*
MultipleVectorCrossoverPipeline is a BreedingPipeline which implements a uniform
(any point) crossover between multiple vectors. It is intended to be used with
three or more vectors. It takes n parent individuals and returns n crossed over
individuals. The number of parents and consequently children is specified by the
number of sources parameter.
The standard vector crossover probability is used for this crossover type.
Note : It is necessary to set the crossover-type parameter to 'any'
in order to use this pipeline.
Typical Number of Individuals Produced Per produce(...) call
number of parents
Number of Sources
variable (generally 3 or more)
Default Base
vector.multixover
*/
// This class is MUCH MUCH longer than it need be. We could just do it by using
// ECJ's generic split and join operations, but only rely on that in the default
// case, and instead use faster per-array operations.
public class MultipleVectorCrossoverPipeline extends BreedingPipeline {
/** default base */
public static final String P_CROSSOVER = "multixover";
/** Temporary holding place for parents */
VectorIndividual[] parents;
public Parameter defaultBase() { return VectorDefaults.base().push(P_CROSSOVER); }
/** Returns the number of parents */
public int numSources() { return DYNAMIC_SOURCES;}
public Object clone()
{
MultipleVectorCrossoverPipeline c = (MultipleVectorCrossoverPipeline)(super.clone());
// deep-cloned stuff
c.parents = (VectorIndividual[]) parents.clone();
return c;
}
public void setup(final EvolutionState state, final Parameter base)
{
super.setup(state,base);
parents = new VectorIndividual[sources.length];
}
/**
* Returns the minimum number of children that are produced per crossover
*/
public int typicalIndsProduced()
{
return minChildProduction()*sources.length; // minChild is always 1
}
public int produce(final int min,
final int max,
final int start,
final int subpopulation,
final Individual[] inds,
final EvolutionState state,
final int thread)
{
// how many individuals should we make?
int n = typicalIndsProduced();
if (n < min) n = min;
if (n > max) n = max;
// should we bother?
if (!state.random[thread].nextBoolean(likelihood))
return reproduce(n, start, subpopulation, inds, state, thread, true); // DO produce children from source -- we've not done so already
if(inds[0] instanceof BitVectorIndividual)
n = multipleBitVectorCrossover(min, max, start, subpopulation, // redundant reassignment
inds, state, thread);
else if(inds[0] instanceof ByteVectorIndividual)
n = multipleByteVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof DoubleVectorIndividual)
n = multipleDoubleVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof FloatVectorIndividual)
n = multipleFloatVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof IntegerVectorIndividual)
n = multipleIntegerVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof GeneVectorIndividual)
n = multipleGeneVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof LongVectorIndividual)
n = multipleLongVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else if(inds[0] instanceof ShortVectorIndividual)
n = multipleShortVectorCrossover(min, max, start, subpopulation,
inds, state, thread);
else // default crossover -- shouldn't need this unless a new vector type is added
{
// check how many sources are provided
if(sources.length <= 2)
// this method shouldn't be called for just two parents
state.output.error("Only two parents specified!");
// fill up parents:
for(int i = 0;i 0; j--) // no need to shuffle first index at the end
{
// find parent to swap piece with
int parent2 = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
// swap
Object temp = pieces[j][i];
pieces[j][i] = pieces[parent2][i];
pieces[parent2][i] = temp;
}
}
}
// join them and add them to the population starting at the start location
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].join(pieces[i]);
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
boolean temp = ((BitVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((BitVectorIndividual)parents[j]).genome[i] =
((BitVectorIndividual)parents[swapIndex]).genome[i];
((BitVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
byte temp = ((ByteVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((ByteVectorIndividual)parents[j]).genome[i] = ((ByteVectorIndividual)parents[swapIndex]).genome[i];
((ByteVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
double temp = ((DoubleVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((DoubleVectorIndividual)parents[j]).genome[i] = ((DoubleVectorIndividual)parents[swapIndex]).genome[i];
((DoubleVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
float temp = ((FloatVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((FloatVectorIndividual)parents[j]).genome[i] = ((FloatVectorIndividual)parents[swapIndex]).genome[i];
((FloatVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
Gene temp = ((GeneVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((GeneVectorIndividual)parents[j]).genome[i] = ((GeneVectorIndividual)parents[swapIndex]).genome[i];
((GeneVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
int temp = ((IntegerVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((IntegerVectorIndividual)parents[j]).genome[i] = ((IntegerVectorIndividual)parents[swapIndex]).genome[i];
((IntegerVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
long temp = ((LongVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((LongVectorIndividual)parents[j]).genome[i] = ((LongVectorIndividual)parents[swapIndex]).genome[i];
((LongVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q max) n = max;
// fill up parents:
for(int i = 0;i 0; j--)
{
int swapIndex = state.random[thread].nextInt(j); // not inclusive; don't want to swap with self
short temp = ((ShortVectorIndividual) parents[j]).genome[i]; // modifying genomes directly. it's okay since they're clones
((ShortVectorIndividual)parents[j]).genome[i] = ((ShortVectorIndividual)parents[swapIndex]).genome[i];
((ShortVectorIndividual)parents[swapIndex]).genome[i] = temp;
}
}
}
// add to population
for(int i = 0, q = start; i < parents.length; i++, q++)
{
parents[i].evaluated = false;
if(q
Ads help maintain this website.