New GI operators (mutation, crossover) and adaptions
This commit is contained in:
parent
a207014610
commit
628499aab9
@ -32,7 +32,7 @@ import eva2.server.go.individuals.AbstractEAIndividual;
|
|||||||
import eva2.server.go.individuals.ESIndividualDoubleData;
|
import eva2.server.go.individuals.ESIndividualDoubleData;
|
||||||
import eva2.server.go.individuals.GAIndividualDoubleData;
|
import eva2.server.go.individuals.GAIndividualDoubleData;
|
||||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||||
import eva2.server.go.operators.crossover.CrossoverGANPoint;
|
import eva2.server.go.operators.crossover.CrossoverGAGINPoint;
|
||||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||||
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
|
import eva2.server.go.operators.mutation.MutateESFixedStepSize;
|
||||||
import eva2.server.go.operators.mutation.MutateESLocal;
|
import eva2.server.go.operators.mutation.MutateESLocal;
|
||||||
@ -322,7 +322,7 @@ public class GOStandaloneVersion implements InterfaceGOStandalone, InterfacePopu
|
|||||||
this.m_GO.getOptimizer().getPopulation().setTargetSize(100);
|
this.m_GO.getOptimizer().getPopulation().setTargetSize(100);
|
||||||
F1Problem problem = new F1Problem();
|
F1Problem problem = new F1Problem();
|
||||||
tmpIndy = new GAIndividualDoubleData();
|
tmpIndy = new GAIndividualDoubleData();
|
||||||
((GAIndividualDoubleData)tmpIndy).setCrossoverOperator(new CrossoverGANPoint());
|
((GAIndividualDoubleData)tmpIndy).setCrossoverOperator(new CrossoverGAGINPoint());
|
||||||
((GAIndividualDoubleData)tmpIndy).setCrossoverProbability(1.0);
|
((GAIndividualDoubleData)tmpIndy).setCrossoverProbability(1.0);
|
||||||
((GAIndividualDoubleData)tmpIndy).setMutationProbability(1.0);
|
((GAIndividualDoubleData)tmpIndy).setMutationProbability(1.0);
|
||||||
((F1Problem)problem).setEAIndividual(tmpIndy);
|
((F1Problem)problem).setEAIndividual(tmpIndy);
|
||||||
|
@ -3,7 +3,7 @@ package eva2.server.go.individuals;
|
|||||||
|
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
|
||||||
import eva2.server.go.operators.crossover.CrossoverGANPoint;
|
import eva2.server.go.operators.crossover.CrossoverGAGINPoint;
|
||||||
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
||||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||||
import eva2.server.go.operators.mutation.MutateGANBit;
|
import eva2.server.go.operators.mutation.MutateGANBit;
|
||||||
@ -27,7 +27,7 @@ public class GAIndividualBinaryData extends AbstractEAIndividual implements Inte
|
|||||||
this.m_MutationProbability = 0.1;
|
this.m_MutationProbability = 0.1;
|
||||||
this.m_MutationOperator = new MutateGANBit();
|
this.m_MutationOperator = new MutateGANBit();
|
||||||
this.m_CrossoverProbability = 1.0;
|
this.m_CrossoverProbability = 1.0;
|
||||||
this.m_CrossoverOperator = new CrossoverGANPoint();
|
this.m_CrossoverOperator = new CrossoverGAGINPoint();
|
||||||
this.m_GenotypeLength = 20;
|
this.m_GenotypeLength = 20;
|
||||||
this.m_Genotype = new BitSet();
|
this.m_Genotype = new BitSet();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import java.util.BitSet;
|
|||||||
|
|
||||||
import eva2.server.go.individuals.codings.ga.GAStandardCodingDouble;
|
import eva2.server.go.individuals.codings.ga.GAStandardCodingDouble;
|
||||||
import eva2.server.go.individuals.codings.ga.InterfaceGADoubleCoding;
|
import eva2.server.go.individuals.codings.ga.InterfaceGADoubleCoding;
|
||||||
import eva2.server.go.operators.crossover.CrossoverGANPoint;
|
import eva2.server.go.operators.crossover.CrossoverGAGINPoint;
|
||||||
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
||||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||||
import eva2.server.go.operators.mutation.MutateGAUniform;
|
import eva2.server.go.operators.mutation.MutateGAUniform;
|
||||||
@ -33,7 +33,7 @@ public class GAIndividualDoubleData extends AbstractEAIndividual implements Inte
|
|||||||
this.m_MutationProbability = 0.1;
|
this.m_MutationProbability = 0.1;
|
||||||
this.m_MutationOperator = new MutateGAUniform();
|
this.m_MutationOperator = new MutateGAUniform();
|
||||||
this.m_CrossoverProbability = 0.7;
|
this.m_CrossoverProbability = 0.7;
|
||||||
this.m_CrossoverOperator = new CrossoverGANPoint();
|
this.m_CrossoverOperator = new CrossoverGAGINPoint();
|
||||||
this.m_Range = new double[1][2];
|
this.m_Range = new double[1][2];
|
||||||
this.m_Range[0][0] = -10;
|
this.m_Range[0][0] = -10;
|
||||||
this.m_Range[0][1] = 10;
|
this.m_Range[0][1] = 10;
|
||||||
|
@ -5,7 +5,7 @@ import java.util.BitSet;
|
|||||||
|
|
||||||
import eva2.server.go.individuals.codings.ga.GAStandardCodingInteger;
|
import eva2.server.go.individuals.codings.ga.GAStandardCodingInteger;
|
||||||
import eva2.server.go.individuals.codings.ga.InterfaceGAIntegerCoding;
|
import eva2.server.go.individuals.codings.ga.InterfaceGAIntegerCoding;
|
||||||
import eva2.server.go.operators.crossover.CrossoverGANPoint;
|
import eva2.server.go.operators.crossover.CrossoverGAGINPoint;
|
||||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||||
import eva2.server.go.operators.mutation.MutateGANBit;
|
import eva2.server.go.operators.mutation.MutateGANBit;
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
@ -31,7 +31,7 @@ public class GAIndividualIntegerData extends AbstractEAIndividual implements Int
|
|||||||
this.m_MutationProbability = 0.2;
|
this.m_MutationProbability = 0.2;
|
||||||
this.m_MutationOperator = new MutateGANBit();
|
this.m_MutationOperator = new MutateGANBit();
|
||||||
this.m_CrossoverProbability = 0.7;
|
this.m_CrossoverProbability = 0.7;
|
||||||
this.m_CrossoverOperator = new CrossoverGANPoint();
|
this.m_CrossoverOperator = new CrossoverGAGINPoint();
|
||||||
this.m_Range = new int[1][2];
|
this.m_Range = new int[1][2];
|
||||||
this.m_CodingLenghts = new int[1];
|
this.m_CodingLenghts = new int[1];
|
||||||
this.m_CodingLenghts[0] = 3;
|
this.m_CodingLenghts[0] = 3;
|
||||||
|
@ -33,6 +33,11 @@ public class GIIndividualIntegerData extends AbstractEAIndividual implements Int
|
|||||||
this.m_Genotype = new int[10];
|
this.m_Genotype = new int[10];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GIIndividualIntegerData(int[][] theRange) {
|
||||||
|
this();
|
||||||
|
SetIntRange(theRange);
|
||||||
|
}
|
||||||
|
|
||||||
public GIIndividualIntegerData(GIIndividualIntegerData individual) {
|
public GIIndividualIntegerData(GIIndividualIntegerData individual) {
|
||||||
if (individual.m_Phenotype != null) {
|
if (individual.m_Phenotype != null) {
|
||||||
this.m_Phenotype = new int[individual.m_Phenotype.length];
|
this.m_Phenotype = new int[individual.m_Phenotype.length];
|
||||||
@ -132,14 +137,12 @@ public class GIIndividualIntegerData extends AbstractEAIndividual implements Int
|
|||||||
*/
|
*/
|
||||||
public void SetIntRange(int[][] range) {
|
public void SetIntRange(int[][] range) {
|
||||||
if (range.length != this.m_Range.length) {
|
if (range.length != this.m_Range.length) {
|
||||||
System.out.println("Warning: Trying to set a range of length " + range.length + " to a vector of length "
|
this.setIntegerDataLength(range.length);
|
||||||
+ this.m_Range.length + "!\n Use method setDoubleDataLength first!");
|
|
||||||
}
|
}
|
||||||
for (int i = 0; ((i < this.m_Range.length) && (i < range.length)); i++) {
|
for (int i = 0; ((i < this.m_Range.length) && (i < range.length)); i++) {
|
||||||
this.m_Range[i][0] = range[i][0];
|
this.m_Range[i][0] = range[i][0];
|
||||||
this.m_Range[i][1] = range[i][1];
|
this.m_Range[i][1] = range[i][1];
|
||||||
}
|
}
|
||||||
this.setIntegerDataLength(range.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This method will return the range for all double attributes.
|
/** This method will return the range for all double attributes.
|
||||||
|
@ -23,7 +23,7 @@ public interface InterfaceGIIndividual {
|
|||||||
|
|
||||||
/** This method will set the range of the int attributes.
|
/** This method will set the range of the int attributes.
|
||||||
* Note: range[d][0] gives the lower bound and range[d] gives the upper bound
|
* Note: range[d][0] gives the lower bound and range[d] gives the upper bound
|
||||||
* for dimension d.
|
* for dimension d where both are included.
|
||||||
* @param range The new range for the int data.
|
* @param range The new range for the int data.
|
||||||
*/
|
*/
|
||||||
public void SetIntRange(int[][] range);
|
public void SetIntRange(int[][] range);
|
||||||
|
266
src/eva2/server/go/operators/crossover/CrossoverGAGINPoint.java
Normal file
266
src/eva2/server/go/operators/crossover/CrossoverGAGINPoint.java
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
package eva2.server.go.operators.crossover;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import eva2.gui.BeanInspector;
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGIIndividual;
|
||||||
|
import eva2.server.go.populations.Population;
|
||||||
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
import eva2.tools.math.RNG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The famous n-point crossover operator on a binary and integer genotype. Genotypes of
|
||||||
|
* parent individuals are recombined by exchanging subsegments within randomly
|
||||||
|
* selected points. Therefore, far-away allels (larger GA schemas) are more likely to be split
|
||||||
|
* between individuals.
|
||||||
|
*
|
||||||
|
* @author mkron, streiche
|
||||||
|
*/
|
||||||
|
public class CrossoverGAGINPoint implements InterfaceCrossover, java.io.Serializable {
|
||||||
|
// private InterfaceOptimizationProblem m_OptimizationProblem;
|
||||||
|
private int m_NumberOfCrossovers = 3;
|
||||||
|
private static boolean TRACE=false;
|
||||||
|
|
||||||
|
public CrossoverGAGINPoint() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrossoverGAGINPoint(int nPoints) {
|
||||||
|
this();
|
||||||
|
setNumberOfCrossovers(nPoints);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CrossoverGAGINPoint(CrossoverGAGINPoint mutator) {
|
||||||
|
// this.m_OptimizationProblem = mutator.m_OptimizationProblem;
|
||||||
|
this.m_NumberOfCrossovers = mutator.m_NumberOfCrossovers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method will enable you to clone a given crossover operator
|
||||||
|
* @return The clone
|
||||||
|
*/
|
||||||
|
public Object clone() {
|
||||||
|
return new CrossoverGAGINPoint(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getGenotype(AbstractEAIndividual individual) {
|
||||||
|
Object genotype=null;
|
||||||
|
if (individual instanceof InterfaceGAIndividual) {
|
||||||
|
genotype = ((InterfaceGAIndividual)individual).getBGenotype();
|
||||||
|
} else {
|
||||||
|
genotype = ((InterfaceGIIndividual)individual).getIGenotype();
|
||||||
|
}
|
||||||
|
return genotype;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractEAIndividual[] mate(AbstractEAIndividual individual, Population partners) {
|
||||||
|
AbstractEAIndividual[] result = null;
|
||||||
|
result = new AbstractEAIndividual[partners.size()+1];
|
||||||
|
result[0] = (AbstractEAIndividual) (individual).clone();
|
||||||
|
for (int i = 0; i < partners.size(); i++) {
|
||||||
|
result[i+1] = (AbstractEAIndividual) ((AbstractEAIndividual)partners.get(i)).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partners.size() == 0) return result;
|
||||||
|
|
||||||
|
if (individual instanceof InterfaceGAIndividual || (individual instanceof InterfaceGIIndividual)) {
|
||||||
|
int length = getGenotypeLength(individual);
|
||||||
|
// Object[][] tmpGenotypes = new Object[2][partners.size()+1];
|
||||||
|
Object[] origGenotypes = new Object[partners.size()+1];
|
||||||
|
Object[] newGenotypes = new Object[partners.size()+1];
|
||||||
|
|
||||||
|
origGenotypes[0] = getGenotype(individual);
|
||||||
|
newGenotypes[0] = getGenotype(result[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < partners.size(); i++) { // clone all individuals
|
||||||
|
origGenotypes[i+1] = getGenotype(partners.getEAIndividual(i));
|
||||||
|
newGenotypes[i+1] = getGenotype(result[i+1]);
|
||||||
|
length = Math.max(length, getGenotypeLength(partners.getEAIndividual(i)));
|
||||||
|
}
|
||||||
|
if (TRACE) System.out.println("Before CO: " + BeanInspector.toString(newGenotypes));
|
||||||
|
int mixer = RNG.randomInt(0, partners.size()); // partner index with which to exchange genes
|
||||||
|
int[] crossoverPoints=getCrossoverPoints(length, m_NumberOfCrossovers);
|
||||||
|
if (TRACE) System.out.println("CO points: " + BeanInspector.toString(crossoverPoints));
|
||||||
|
for (int i = 0; i < length; i++) { // loop positions
|
||||||
|
for (int j = 0; j < this.m_NumberOfCrossovers; j++) {
|
||||||
|
if (i == crossoverPoints[j]) mixer++; // possibly switch partner to exchange with
|
||||||
|
}
|
||||||
|
for (int j = 0; j < origGenotypes.length; j++) { // loop individuals
|
||||||
|
// exchange values at position i between indies
|
||||||
|
exchangePos(origGenotypes, newGenotypes, (j+mixer) % origGenotypes.length, j, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
writeBack(result[i], newGenotypes[i]);
|
||||||
|
}
|
||||||
|
if (TRACE) System.out.println("After CO: " + BeanInspector.toString(newGenotypes));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeBack(AbstractEAIndividual indy,
|
||||||
|
Object newGenotype) {
|
||||||
|
if (indy instanceof InterfaceGAIndividual) {
|
||||||
|
((InterfaceGAIndividual)indy).SetBGenotype((BitSet)newGenotype);
|
||||||
|
} else {
|
||||||
|
((InterfaceGIIndividual)indy).SetIGenotype((int[])newGenotype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void exchangePos(Object[] origGenotypes, Object[] newGenotypes, int a, int b, int position) {
|
||||||
|
setVal(newGenotypes[a], position, getVal(origGenotypes[b], position));
|
||||||
|
setVal(newGenotypes[b], position, getVal(origGenotypes[a], position));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setVal(Object genotype, int position, Object val) {
|
||||||
|
if (genotype instanceof BitSet) {
|
||||||
|
((BitSet)genotype).set(position, (Boolean)val);
|
||||||
|
} else {
|
||||||
|
((int[])genotype)[position]=(Integer)val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getVal(Object genotype, int position) {
|
||||||
|
if (genotype instanceof BitSet) {
|
||||||
|
return ((BitSet)genotype).get(position);
|
||||||
|
} else {
|
||||||
|
return ((int[])genotype)[position];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getGenotypeLength(AbstractEAIndividual individual) {
|
||||||
|
if (individual instanceof InterfaceGAIndividual) {
|
||||||
|
return ((InterfaceGAIndividual)individual).getGenotypeLength();
|
||||||
|
} else {
|
||||||
|
return((InterfaceGIIndividual)individual).getGenotypeLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// /** This method performs crossover on multiple individuals. If the individuals do
|
||||||
|
// * not implement InterfaceGAIndividual, then nothing will happen.
|
||||||
|
// * @param indy1 The first individual
|
||||||
|
// * @param partners The second individual
|
||||||
|
// */
|
||||||
|
// public AbstractEAIndividual[] mateOld(AbstractEAIndividual indy1, Population partners) {
|
||||||
|
// AbstractEAIndividual[] result = null;
|
||||||
|
// result = new AbstractEAIndividual[partners.size()+1];
|
||||||
|
// result[0] = (AbstractEAIndividual) (indy1).clone();
|
||||||
|
// for (int i = 0; i < partners.size(); i++) {
|
||||||
|
// result[i+1] = (AbstractEAIndividual) ((AbstractEAIndividual)partners.get(i)).clone();
|
||||||
|
// }
|
||||||
|
// if (partners.size() == 0) return result;
|
||||||
|
// //for (int i = 0; i < result.length; i++) System.out.println("Before Crossover: " +result[i].getSolutionRepresentationFor());
|
||||||
|
// if ((indy1 instanceof InterfaceGAIndividual) && (partners.get(0) instanceof InterfaceGAIndividual)) {
|
||||||
|
// int length = ((InterfaceGAIndividual)indy1).getGenotypeLength();
|
||||||
|
// int mixer = RNG.randomInt(0, partners.size());
|
||||||
|
// int[] crossoverPoints = null;
|
||||||
|
// BitSet[][] tmpBitSet = new BitSet[2][partners.size()+1];
|
||||||
|
//
|
||||||
|
// tmpBitSet[0][0] = ((InterfaceGAIndividual)indy1).getBGenotype();
|
||||||
|
// tmpBitSet[1][0] = ((InterfaceGAIndividual)result[0]).getBGenotype();
|
||||||
|
// for (int i = 0; i < partners.size(); i++) {
|
||||||
|
// tmpBitSet[0][i+1] = ((InterfaceGAIndividual)partners.get(i)).getBGenotype();
|
||||||
|
// tmpBitSet[1][i+1] = ((InterfaceGAIndividual)result[i+1]).getBGenotype();
|
||||||
|
// length = Math.max(length, ((InterfaceGAIndividual)partners.get(i)).getGenotypeLength());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// crossoverPoints=getCrossoverPoints(length, m_NumberOfCrossovers);
|
||||||
|
//
|
||||||
|
// for (int i = 0; i < length; i++) {
|
||||||
|
// for (int j = 0; j < this.m_NumberOfCrossovers; j++) {
|
||||||
|
// if (i == crossoverPoints[j]) mixer++;
|
||||||
|
// }
|
||||||
|
// for (int j = 0; j < tmpBitSet[0].length; j++) {
|
||||||
|
// //if ((mixer % tmpBitSet[0].length) != 0) {
|
||||||
|
// //System.out.println(""+((j + mixer) % tmpBitSet[0].length)+ " - " + (j + mixer) +" - "+(tmpBitSet[0].length));
|
||||||
|
// if (tmpBitSet[0][(j + mixer) % tmpBitSet[0].length].get(i)) tmpBitSet[1][j].set(i);
|
||||||
|
// else tmpBitSet[1][j].clear(i);
|
||||||
|
// //}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for (int i = 0; i < result.length; i++) ((InterfaceGAIndividual)result[i]).SetBGenotype(tmpBitSet[1][i]);
|
||||||
|
// }
|
||||||
|
// //in case the crossover was successful lets give the mutation operators a chance to mate the strategy parameters
|
||||||
|
// for (int i = 0; i < result.length; i++) result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, partners);
|
||||||
|
// //for (int i = 0; i < result.length; i++) System.out.println("After Crossover: " +result[i].getSolutionRepresentationFor());
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the crossover points within the genotype of given length.
|
||||||
|
* @param length
|
||||||
|
* @param numberOfCrossovers
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected int[] getCrossoverPoints(int length, int numberOfCrossovers) {
|
||||||
|
int[] crossoverPoints = new int[numberOfCrossovers];
|
||||||
|
for (int i = 0; i < numberOfCrossovers; i++) {
|
||||||
|
crossoverPoints[i] = RNG.randomInt(0, length-1);
|
||||||
|
}
|
||||||
|
return crossoverPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to evaluate wether two crossover operators
|
||||||
|
* are actually the same.
|
||||||
|
* @param crossover The other crossover operator
|
||||||
|
*/
|
||||||
|
public boolean equals(Object crossover) {
|
||||||
|
if (crossover instanceof CrossoverGAGINPoint) {
|
||||||
|
CrossoverGAGINPoint cross = (CrossoverGAGINPoint)crossover;
|
||||||
|
if (this.m_NumberOfCrossovers != cross.m_NumberOfCrossovers) return false;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method will allow the crossover operator to be initialized depending on the
|
||||||
|
* individual and the optimization problem. The optimization problem is to be stored
|
||||||
|
* since it is to be called during crossover to calculate the exogene parameters for
|
||||||
|
* the offsprings.
|
||||||
|
* @param individual The individual that will be mutated.
|
||||||
|
* @param opt The optimization problem.
|
||||||
|
*/
|
||||||
|
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
|
||||||
|
// this.m_OptimizationProblem = opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringRepresentation() {
|
||||||
|
return this.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************
|
||||||
|
* These are for GUI
|
||||||
|
*/
|
||||||
|
/** This method allows the CommonJavaObjectEditorPanel to read the
|
||||||
|
* name to the current object.
|
||||||
|
* @return The name.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return "GA-GI N-Point Crossover";
|
||||||
|
}
|
||||||
|
/** This method returns a global info string
|
||||||
|
* @return description
|
||||||
|
*/
|
||||||
|
public static String globalInfo() {
|
||||||
|
return "This is an n-point crossover between m individuals which may be binary or integer based.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to set the number of crossovers that occur in the
|
||||||
|
* genotype.
|
||||||
|
* @param crossovers The number of crossovers.
|
||||||
|
*/
|
||||||
|
public void setNumberOfCrossovers(int crossovers) {
|
||||||
|
if (crossovers < 0) crossovers = 0;
|
||||||
|
this.m_NumberOfCrossovers = crossovers;
|
||||||
|
}
|
||||||
|
public int getNumberOfCrossovers() {
|
||||||
|
return this.m_NumberOfCrossovers;
|
||||||
|
}
|
||||||
|
public String numberOfCrossoversTipText() {
|
||||||
|
return "The number of crossoverpoints.";
|
||||||
|
}
|
||||||
|
}
|
@ -10,31 +10,31 @@ import eva2.tools.math.RNG;
|
|||||||
* @author mkron
|
* @author mkron
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CrossoverGANPointSegmentwise extends CrossoverGANPoint {
|
public class CrossoverGAGINPointSegmentwise extends CrossoverGAGINPoint {
|
||||||
int segmentLength=8;
|
int segmentLength=8;
|
||||||
|
|
||||||
public CrossoverGANPointSegmentwise() {
|
public CrossoverGAGINPointSegmentwise() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CrossoverGANPointSegmentwise(CrossoverGANPointSegmentwise o) {
|
public CrossoverGAGINPointSegmentwise(CrossoverGAGINPointSegmentwise o) {
|
||||||
super(o);
|
super(o);
|
||||||
this.segmentLength=o.segmentLength;
|
this.segmentLength=o.segmentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CrossoverGANPointSegmentwise(int nPoints, int segmentLen) {
|
public CrossoverGAGINPointSegmentwise(int nPoints, int segmentLen) {
|
||||||
super(nPoints);
|
super(nPoints);
|
||||||
setSegmentLength(segmentLen);
|
setSegmentLength(segmentLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object clone() {
|
public Object clone() {
|
||||||
return new CrossoverGANPointSegmentwise(this);
|
return new CrossoverGAGINPointSegmentwise(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object crossover) {
|
public boolean equals(Object crossover) {
|
||||||
if (super.equals(crossover) && (crossover instanceof CrossoverGANPointSegmentwise)) {
|
if (super.equals(crossover) && (crossover instanceof CrossoverGAGINPointSegmentwise)) {
|
||||||
return ((CrossoverGANPointSegmentwise)crossover).segmentLength==this.segmentLength;
|
return ((CrossoverGAGINPointSegmentwise)crossover).segmentLength==this.segmentLength;
|
||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ public class CrossoverGANPointSegmentwise extends CrossoverGANPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "GA N-Point segment-wise crossover";
|
return "GA-GI N-Point segment-wise crossover";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String globalInfo() {
|
public static String globalInfo() {
|
@ -1,168 +0,0 @@
|
|||||||
package eva2.server.go.operators.crossover;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
|
||||||
|
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
|
||||||
import eva2.server.go.individuals.InterfaceGAIndividual;
|
|
||||||
import eva2.server.go.populations.Population;
|
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
|
||||||
import eva2.tools.math.RNG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The famous n-point crossover operator on a binary genotype. Genotypes of
|
|
||||||
* parent individuals are recombined by exchanging subsegments within randomly
|
|
||||||
* selected points. Therefore, far-away allels (larger GA schemas) are more likely to be split
|
|
||||||
* between individuals.
|
|
||||||
*
|
|
||||||
* @author mkron, streiche
|
|
||||||
*/
|
|
||||||
public class CrossoverGANPoint implements InterfaceCrossover, java.io.Serializable {
|
|
||||||
// private InterfaceOptimizationProblem m_OptimizationProblem;
|
|
||||||
private int m_NumberOfCrossovers = 3;
|
|
||||||
|
|
||||||
public CrossoverGANPoint() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public CrossoverGANPoint(int nPoints) {
|
|
||||||
this();
|
|
||||||
setNumberOfCrossovers(nPoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CrossoverGANPoint(CrossoverGANPoint mutator) {
|
|
||||||
// this.m_OptimizationProblem = mutator.m_OptimizationProblem;
|
|
||||||
this.m_NumberOfCrossovers = mutator.m_NumberOfCrossovers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method will enable you to clone a given crossover operator
|
|
||||||
* @return The clone
|
|
||||||
*/
|
|
||||||
public Object clone() {
|
|
||||||
return new CrossoverGANPoint(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method performs crossover on multiple individuals. If the individuals do
|
|
||||||
* not implement InterfaceGAIndividual, then nothing will happen.
|
|
||||||
* @param indy1 The first individual
|
|
||||||
* @param partners The second individual
|
|
||||||
*/
|
|
||||||
public AbstractEAIndividual[] mate(AbstractEAIndividual indy1, Population partners) {
|
|
||||||
AbstractEAIndividual[] result = null;
|
|
||||||
result = new AbstractEAIndividual[partners.size()+1];
|
|
||||||
result[0] = (AbstractEAIndividual) (indy1).clone();
|
|
||||||
for (int i = 0; i < partners.size(); i++) {
|
|
||||||
result[i+1] = (AbstractEAIndividual) ((AbstractEAIndividual)partners.get(i)).clone();
|
|
||||||
}
|
|
||||||
if (partners.size() == 0) return result;
|
|
||||||
//for (int i = 0; i < result.length; i++) System.out.println("Before Crossover: " +result[i].getSolutionRepresentationFor());
|
|
||||||
if ((indy1 instanceof InterfaceGAIndividual) && (partners.get(0) instanceof InterfaceGAIndividual)) {
|
|
||||||
int length = ((InterfaceGAIndividual)indy1).getGenotypeLength();
|
|
||||||
int mixer = RNG.randomInt(0, partners.size());
|
|
||||||
int[] crossoverPoints = null;
|
|
||||||
BitSet[][] tmpBitSet = new BitSet[2][partners.size()+1];
|
|
||||||
|
|
||||||
tmpBitSet[0][0] = ((InterfaceGAIndividual)indy1).getBGenotype();
|
|
||||||
tmpBitSet[1][0] = ((InterfaceGAIndividual)result[0]).getBGenotype();
|
|
||||||
for (int i = 0; i < partners.size(); i++) {
|
|
||||||
tmpBitSet[0][i+1] = ((InterfaceGAIndividual)partners.get(i)).getBGenotype();
|
|
||||||
tmpBitSet[1][i+1] = ((InterfaceGAIndividual)result[i+1]).getBGenotype();
|
|
||||||
length = Math.max(length, ((InterfaceGAIndividual)partners.get(i)).getGenotypeLength());
|
|
||||||
}
|
|
||||||
|
|
||||||
crossoverPoints=getCrossoverPoints(length, m_NumberOfCrossovers);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
for (int j = 0; j < this.m_NumberOfCrossovers; j++) {
|
|
||||||
if (i == crossoverPoints[j]) mixer++;
|
|
||||||
}
|
|
||||||
for (int j = 0; j < tmpBitSet[0].length; j++) {
|
|
||||||
//if ((mixer % tmpBitSet[0].length) != 0) {
|
|
||||||
//System.out.println(""+((j + mixer) % tmpBitSet[0].length)+ " - " + (j + mixer) +" - "+(tmpBitSet[0].length));
|
|
||||||
if (tmpBitSet[0][(j + mixer) % tmpBitSet[0].length].get(i)) tmpBitSet[1][j].set(i);
|
|
||||||
else tmpBitSet[1][j].clear(i);
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < result.length; i++) ((InterfaceGAIndividual)result[i]).SetBGenotype(tmpBitSet[1][i]);
|
|
||||||
}
|
|
||||||
//in case the crossover was successful lets give the mutation operators a chance to mate the strategy parameters
|
|
||||||
for (int i = 0; i < result.length; i++) result[i].getMutationOperator().crossoverOnStrategyParameters(indy1, partners);
|
|
||||||
//for (int i = 0; i < result.length; i++) System.out.println("After Crossover: " +result[i].getSolutionRepresentationFor());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Select the crossover points within the genotype of given length.
|
|
||||||
* @param length
|
|
||||||
* @param numberOfCrossovers
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
protected int[] getCrossoverPoints(int length, int numberOfCrossovers) {
|
|
||||||
int[] crossoverPoints = new int[numberOfCrossovers];
|
|
||||||
for (int i = 0; i < numberOfCrossovers; i++) {
|
|
||||||
crossoverPoints[i] = RNG.randomInt(0, length-1);
|
|
||||||
}
|
|
||||||
return crossoverPoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to evaluate wether two crossover operators
|
|
||||||
* are actually the same.
|
|
||||||
* @param crossover The other crossover operator
|
|
||||||
*/
|
|
||||||
public boolean equals(Object crossover) {
|
|
||||||
if (crossover instanceof CrossoverGANPoint) {
|
|
||||||
CrossoverGANPoint cross = (CrossoverGANPoint)crossover;
|
|
||||||
if (this.m_NumberOfCrossovers != cross.m_NumberOfCrossovers) return false;
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method will allow the crossover operator to be initialized depending on the
|
|
||||||
* individual and the optimization problem. The optimization problem is to be stored
|
|
||||||
* since it is to be called during crossover to calculate the exogene parameters for
|
|
||||||
* the offsprings.
|
|
||||||
* @param individual The individual that will be mutated.
|
|
||||||
* @param opt The optimization problem.
|
|
||||||
*/
|
|
||||||
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
|
|
||||||
// this.m_OptimizationProblem = opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getStringRepresentation() {
|
|
||||||
return this.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************
|
|
||||||
* These are for GUI
|
|
||||||
*/
|
|
||||||
/** This method allows the CommonJavaObjectEditorPanel to read the
|
|
||||||
* name to the current object.
|
|
||||||
* @return The name.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return "GA N-Point Crossover";
|
|
||||||
}
|
|
||||||
/** This method returns a global info string
|
|
||||||
* @return description
|
|
||||||
*/
|
|
||||||
public static String globalInfo() {
|
|
||||||
return "This is an n-point crossover between m individuals.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to set the number of crossovers that occur in the
|
|
||||||
* genotype.
|
|
||||||
* @param crossovers The number of crossovers.
|
|
||||||
*/
|
|
||||||
public void setNumberOfCrossovers(int crossovers) {
|
|
||||||
if (crossovers < 0) crossovers = 0;
|
|
||||||
this.m_NumberOfCrossovers = crossovers;
|
|
||||||
}
|
|
||||||
public int getNumberOfCrossovers() {
|
|
||||||
return this.m_NumberOfCrossovers;
|
|
||||||
}
|
|
||||||
public String numberOfCrossoversTipText() {
|
|
||||||
return "The number of crossoverpoints.";
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,240 @@
|
|||||||
|
package eva2.server.go.operators.initialization;
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGIIndividual;
|
||||||
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
import eva2.tools.EVAERROR;
|
||||||
|
import eva2.tools.math.RNG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An initialization method which sets a fixed number of specified values per segment,
|
||||||
|
* where a segment is a connected subsequence of the genotype.
|
||||||
|
* This is usable for binary and integer individuals only.
|
||||||
|
* For binary individuals, this allows to control the number of bits per segment. For
|
||||||
|
* integer individuals, it allows to control the number of occurences of a certain integer
|
||||||
|
* per segment. It may also be used to initialize with subsets of integers (by setting 0
|
||||||
|
* elements to a certain type and all to a subset of the range).
|
||||||
|
*
|
||||||
|
* The initialization may be parameterized in two ways, where each takes a fixed
|
||||||
|
* segment length s. Firstly, a fixed number of bits (k<=s) is set per segment,
|
||||||
|
* so each segment has equal cardinality.
|
||||||
|
* Secondly, an int-array can be specified which defines possibly varying k_i for
|
||||||
|
* each segment i, so different segments may have different cardinality. The array
|
||||||
|
* must comply to the binary genotype length of the problem. The array definition
|
||||||
|
* has strict priority over the fixed cardinality definition.
|
||||||
|
*
|
||||||
|
* @author mkron
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class GAGIInitializeSegmentwise implements InterfaceInitialization, java.io.Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
protected int[] bitsPerSegmentArray = new int[0];
|
||||||
|
private int bitsPerSegment=1;
|
||||||
|
private int segmentLength=4;
|
||||||
|
private int targetElement=1;
|
||||||
|
private int[] otherElements=new int[]{};
|
||||||
|
|
||||||
|
public GAGIInitializeSegmentwise() {}
|
||||||
|
|
||||||
|
public GAGIInitializeSegmentwise(GAGIInitializeSegmentwise o) {
|
||||||
|
bitsPerSegment = o.bitsPerSegment;
|
||||||
|
segmentLength = o.segmentLength;
|
||||||
|
targetElement = o.targetElement;
|
||||||
|
if (o.otherElements!= null) {
|
||||||
|
otherElements= new int[o.otherElements.length];
|
||||||
|
System.arraycopy(o.otherElements, 0, otherElements, 0, otherElements.length);
|
||||||
|
}
|
||||||
|
if (o.bitsPerSegmentArray!=null) {
|
||||||
|
bitsPerSegmentArray = new int[o.bitsPerSegmentArray.length];
|
||||||
|
System.arraycopy(o.bitsPerSegmentArray, 0, bitsPerSegmentArray, 0, bitsPerSegmentArray.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GAGIInitializeSegmentwise(int segLen, int[] bitsPerSeg) {
|
||||||
|
segmentLength = segLen;
|
||||||
|
bitsPerSegmentArray = bitsPerSeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the integer case defining the target element and other elements.
|
||||||
|
*
|
||||||
|
* @param segLen
|
||||||
|
* @param bitsPerSeg
|
||||||
|
* @param targetElement
|
||||||
|
* @param otherElements
|
||||||
|
*/
|
||||||
|
public GAGIInitializeSegmentwise(int segLen, int[] bitsPerSeg, int targetElement, int[] otherElements) {
|
||||||
|
segmentLength = segLen;
|
||||||
|
bitsPerSegmentArray = bitsPerSeg;
|
||||||
|
this.targetElement = targetElement;
|
||||||
|
this.otherElements = otherElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InterfaceInitialization clone() {
|
||||||
|
return new GAGIInitializeSegmentwise(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initialize(AbstractEAIndividual indy,
|
||||||
|
InterfaceOptimizationProblem problem) {
|
||||||
|
if (indy instanceof InterfaceGAIndividual || indy instanceof InterfaceGIIndividual) {
|
||||||
|
int genotypeLen=-1;
|
||||||
|
Object genotype=null;
|
||||||
|
int[][] intRange=null; // may remain null in the binary case
|
||||||
|
if (indy instanceof InterfaceGAIndividual) {
|
||||||
|
genotypeLen = ((InterfaceGAIndividual)indy).getGenotypeLength();
|
||||||
|
genotype = ((InterfaceGAIndividual)indy).getBGenotype();
|
||||||
|
} else {
|
||||||
|
genotypeLen = ((InterfaceGIIndividual)indy).getGenotypeLength();
|
||||||
|
genotype = ((InterfaceGIIndividual)indy).getIGenotype();
|
||||||
|
intRange = ((InterfaceGIIndividual)indy).getIntRange();
|
||||||
|
}
|
||||||
|
if (bitsPerSegmentArray==null || (bitsPerSegmentArray.length==0)) {
|
||||||
|
// regard only a fixed number of bits per segment
|
||||||
|
for (int i=0; i<genotypeLen; i+=segmentLength) {
|
||||||
|
// create the next segment
|
||||||
|
BitSet nextSeg=RNG.randomBitSet(bitsPerSegment, segmentLength);
|
||||||
|
setNewVals(nextSeg, genotype, i, genotypeLen, intRange);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else { // the number of bits to set may vary from segment to segment.
|
||||||
|
if (bitsPerSegmentArray.length * segmentLength != genotypeLen) EVAERROR.errorMsgOnce("Warning, potential mismatch between segment lengths and genotype length in " + this.getClass());
|
||||||
|
if (bitsPerSegmentArray.length * segmentLength < genotypeLen) System.err.println("Warning, " + (genotypeLen - bitsPerSegmentArray.length * segmentLength) + " bits will not be initialized!");
|
||||||
|
for (int s=0; s<bitsPerSegmentArray.length; s++) {
|
||||||
|
// look at each segment individually
|
||||||
|
BitSet nextSeg=RNG.randomBitSet(bitsPerSegmentArray[s], segmentLength);
|
||||||
|
setNewVals(nextSeg, genotype, s*segmentLength, genotypeLen, intRange);
|
||||||
|
// for (int k=(s)*segmentLength; k<(s+1)*segmentLength; k++) {
|
||||||
|
// if (k<genotypeLen) genotype.set(k, nextSeg.get(k-(s*segmentLength)));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write back the genotype (it may have been cloned, who knows...)
|
||||||
|
if (indy instanceof InterfaceGAIndividual) {
|
||||||
|
((InterfaceGAIndividual)indy).SetBGenotype((BitSet)genotype);
|
||||||
|
} else {
|
||||||
|
((InterfaceGIIndividual)indy).SetIGenotype((int[])genotype);
|
||||||
|
}
|
||||||
|
// System.out.println(BeanInspector.toString(genotype));
|
||||||
|
} else throw new RuntimeException("Error: "+ this.getClass() + " must be used with binary or integer individuals!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Treat both the binary and the integer case.
|
||||||
|
*
|
||||||
|
* @param nextSeg
|
||||||
|
* @param genotype
|
||||||
|
* @param offset
|
||||||
|
* @param maxLen
|
||||||
|
* @param intRange
|
||||||
|
*/
|
||||||
|
private void setNewVals(BitSet nextSeg, Object genotype, int offset, int maxLen, int[][] intRange) {
|
||||||
|
// the bits in the nextSeg bitset define the structure of the next segment starting at the offset.
|
||||||
|
// maxLen is the length of the full data type.
|
||||||
|
for (int k=offset;k<offset+segmentLength; k++) {
|
||||||
|
// transfer the new segment to the genotype
|
||||||
|
if (k<maxLen) {
|
||||||
|
if (genotype instanceof BitSet) { // binary case
|
||||||
|
((BitSet)genotype).set(k, getBoolVal(nextSeg.get(k-offset)));
|
||||||
|
} else if (genotype instanceof int[]) { // integer case
|
||||||
|
((int[])genotype)[k]=getIntVal(nextSeg.get(k-offset), k, intRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the integer value selected at the given position.
|
||||||
|
* @param initBit
|
||||||
|
* @param pos
|
||||||
|
* @param range
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int getIntVal(boolean initBit, int pos, int[][] range) {
|
||||||
|
// if true, the target value is returned, otherwise the non-target value
|
||||||
|
// or a random value in range
|
||||||
|
if (initBit) return targetElement;
|
||||||
|
else {
|
||||||
|
if ((otherElements==null) || (otherElements.length==0)) { // all but the one to set
|
||||||
|
int rangeLenMinusOne = range[pos][1]-range[pos][0]; // bounds are included, so one is missing
|
||||||
|
int newVal=RNG.randomInt(rangeLenMinusOne); // a random integer with one missing (the largest)
|
||||||
|
if (newVal>=targetElement) newVal++; // make sure the elementToSet is not returned but all others may be, including the largest
|
||||||
|
return newVal;
|
||||||
|
} else {
|
||||||
|
// select one randomly from the array
|
||||||
|
int k=RNG.randomInt(otherElements.length);
|
||||||
|
return otherElements[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getBoolVal(boolean initBit) {
|
||||||
|
// the new value is TRUE if the nextSeg-bit is set and 1 is set as target value,
|
||||||
|
// otherwise FALSE (if target value is 0) -- thus target value=1 and
|
||||||
|
// bitsPerSegment=k is equivalent to target value=0 and bitsPerSegment=segmentLength-k
|
||||||
|
if (initBit) return (targetElement==1);
|
||||||
|
else return (targetElement!=1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getBitsPerSegmentArray() {
|
||||||
|
return bitsPerSegmentArray;
|
||||||
|
}
|
||||||
|
public void setBitsPerSegmentArray(int[] bitsPerSegmentArray) {
|
||||||
|
this.bitsPerSegmentArray = bitsPerSegmentArray;
|
||||||
|
}
|
||||||
|
public String bitsPerSegmentArrayTipText() {
|
||||||
|
return "A value per segment defining the number of bits to set for that segment, or null if fixed";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBitsPerSegment() {
|
||||||
|
return bitsPerSegment;
|
||||||
|
}
|
||||||
|
public void setBitsPerSegment(int bitsPerSegment) {
|
||||||
|
this.bitsPerSegment = bitsPerSegment;
|
||||||
|
}
|
||||||
|
public String bitsPerSegmentTipText() {
|
||||||
|
return "If not array-wise defined, this fixed number of bits is set per segment";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSegmentLength() {
|
||||||
|
return segmentLength;
|
||||||
|
}
|
||||||
|
public void setSegmentLength(int segmentLength) {
|
||||||
|
this.segmentLength = segmentLength;
|
||||||
|
}
|
||||||
|
public String segmentLengthTipText() {
|
||||||
|
return "The fixed length of a segment, which is a substring of the binary genotype";
|
||||||
|
}
|
||||||
|
|
||||||
|
////////
|
||||||
|
public String getName() {
|
||||||
|
return "GA-GI segment-wise init";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String globalInfo() {
|
||||||
|
return "A method which initializes with a fixed number of occurences per segment, which is a fixed-length" +
|
||||||
|
" substring of equal length. In the binary case, thus the cardinality of each segment can be predefined.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTargetElement() {
|
||||||
|
return targetElement;
|
||||||
|
}
|
||||||
|
public void setTargetElement(int elementToSet) {
|
||||||
|
this.targetElement = elementToSet;
|
||||||
|
}
|
||||||
|
public String targetElementTipText() {
|
||||||
|
return "The element to set in a defined number per segment";
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getOtherElements() {
|
||||||
|
return otherElements;
|
||||||
|
}
|
||||||
|
public void setOtherElements(int[] elementsNotToSet) {
|
||||||
|
this.otherElements = elementsNotToSet;
|
||||||
|
}
|
||||||
|
public String otherElementsTipText() {
|
||||||
|
return "Set of elements at the rest of instances among which is chosen randomly - if empty, all allowed ones except for the elementToSet are used.";
|
||||||
|
}
|
||||||
|
}
|
@ -1,127 +0,0 @@
|
|||||||
package eva2.server.go.operators.initialization;
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
|
||||||
|
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
|
||||||
import eva2.server.go.individuals.InterfaceGAIndividual;
|
|
||||||
import eva2.server.go.individuals.InterfaceGIIndividual;
|
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
|
||||||
import eva2.tools.EVAERROR;
|
|
||||||
import eva2.tools.math.RNG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An initialization method which sets a fixed number of bits per segment,
|
|
||||||
* where a segment is a connected subsequence of the genotype.
|
|
||||||
* This is usable for GA individuals only.
|
|
||||||
*
|
|
||||||
* The initialization may be parameterized in two ways, where each takes a fixed
|
|
||||||
* segment length s. Firstly, a fixed number of bits (k<=s) is set per segment,
|
|
||||||
* so each segment has equal cardinality.
|
|
||||||
* Secondly, an int-array can be specified which defines possibly varying k_i for
|
|
||||||
* each segment i, so different segments may have different cardinaltiy. The array
|
|
||||||
* must comply to the binary genotype length of the problem. The array definition
|
|
||||||
* has strict priority over the fixed cardinality definition.
|
|
||||||
*
|
|
||||||
* @author mkron
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class GAInitializeSegmentwise implements InterfaceInitialization, java.io.Serializable {
|
|
||||||
protected int[] bitsPerSegmentArray = new int[0];
|
|
||||||
private int bitsPerSegment=1;
|
|
||||||
private int segmentLength=4;
|
|
||||||
|
|
||||||
public GAInitializeSegmentwise() {}
|
|
||||||
|
|
||||||
public GAInitializeSegmentwise(GAInitializeSegmentwise o) {
|
|
||||||
bitsPerSegment = o.bitsPerSegment;
|
|
||||||
segmentLength = o.segmentLength;
|
|
||||||
if (o.bitsPerSegmentArray!=null) {
|
|
||||||
bitsPerSegmentArray = new int[o.bitsPerSegmentArray.length];
|
|
||||||
System.arraycopy(o.bitsPerSegmentArray, 0, bitsPerSegmentArray, 0, bitsPerSegmentArray.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public GAInitializeSegmentwise(int segLen, int[] bitsPerSeg) {
|
|
||||||
segmentLength = segLen;
|
|
||||||
bitsPerSegmentArray = bitsPerSeg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public InterfaceInitialization clone() {
|
|
||||||
return new GAInitializeSegmentwise(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initialize(AbstractEAIndividual indy,
|
|
||||||
InterfaceOptimizationProblem problem) {
|
|
||||||
if (indy instanceof InterfaceGAIndividual) {
|
|
||||||
InterfaceGAIndividual gaIndy = ((InterfaceGAIndividual)indy);
|
|
||||||
int genotypeLen = gaIndy.getGenotypeLength();
|
|
||||||
BitSet genotype = gaIndy.getBGenotype();
|
|
||||||
if (bitsPerSegmentArray==null || (bitsPerSegmentArray.length==0)) {
|
|
||||||
// regard only a fixed number of bits per segment
|
|
||||||
for (int i=0; i<genotypeLen; i+=segmentLength) {
|
|
||||||
// create the next segment
|
|
||||||
BitSet nextSeg=RNG.randomBitSet(bitsPerSegment, segmentLength);
|
|
||||||
for (int k=i;k<i+segmentLength; k++) {
|
|
||||||
// transfer the new segment to the genotype
|
|
||||||
if (k<genotypeLen) genotype.set(k, nextSeg.get(k-i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // the number of bits to set may vary from segment to segment.
|
|
||||||
if (bitsPerSegmentArray.length * segmentLength != genotypeLen) EVAERROR.errorMsgOnce("Warning, potential mismatch between segment lengths and genotype length in " + this.getClass());
|
|
||||||
if (bitsPerSegmentArray.length * segmentLength < genotypeLen) System.err.println("Warning, " + (genotypeLen - bitsPerSegmentArray.length * segmentLength) + " bits will not be initialized!");
|
|
||||||
for (int s=0; s<bitsPerSegmentArray.length; s++) {
|
|
||||||
// look at each segment individually
|
|
||||||
BitSet nextSeg=RNG.randomBitSet(bitsPerSegmentArray[s], segmentLength);
|
|
||||||
for (int k=(s)*segmentLength; k<(s+1)*segmentLength; k++) {
|
|
||||||
if (k<genotypeLen) genotype.set(k, nextSeg.get(k-(s*segmentLength)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write back the genotype (it may have been cloned, who knows...)
|
|
||||||
gaIndy.SetBGenotype(genotype);
|
|
||||||
// System.out.println(genotype.cardinality());
|
|
||||||
} else if (indy instanceof InterfaceGIIndividual) {
|
|
||||||
// TODO ADD INTEGER IMPLEMENTATION???
|
|
||||||
} else throw new RuntimeException("Error: "+ this.getClass() + " must be used with individuals of type " + InterfaceGAIndividual.class + "!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getBitsPerSegmentArray() {
|
|
||||||
return bitsPerSegmentArray;
|
|
||||||
}
|
|
||||||
public void setBitsPerSegmentArray(int[] bitsPerSegmentArray) {
|
|
||||||
this.bitsPerSegmentArray = bitsPerSegmentArray;
|
|
||||||
}
|
|
||||||
public String bitsPerSegmentArrayTipText() {
|
|
||||||
return "A value per segment defining the number of bits to set for that segment, or null if fixed";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getBitsPerSegment() {
|
|
||||||
return bitsPerSegment;
|
|
||||||
}
|
|
||||||
public void setBitsPerSegment(int bitsPerSegment) {
|
|
||||||
this.bitsPerSegment = bitsPerSegment;
|
|
||||||
}
|
|
||||||
public String bitsPerSegmentTipText() {
|
|
||||||
return "If not array-wise defined, this fixed number of bits is set per segment";
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSegmentLength() {
|
|
||||||
return segmentLength;
|
|
||||||
}
|
|
||||||
public void setSegmentLength(int segmentLength) {
|
|
||||||
this.segmentLength = segmentLength;
|
|
||||||
}
|
|
||||||
public String segmentLengthTipText() {
|
|
||||||
return "The fixed length of a segment, which is a substring of the binary genotype";
|
|
||||||
}
|
|
||||||
|
|
||||||
////////
|
|
||||||
public String getName() {
|
|
||||||
return "GA segment-wise init";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String globalInfo() {
|
|
||||||
return "A method which initializes a fixed number of bits per binary segment, which is a fixed number" +
|
|
||||||
"of bits for substrings of equal length";
|
|
||||||
}
|
|
||||||
}
|
|
235
src/eva2/server/go/operators/mutation/MutateGAGISwapBits.java
Normal file
235
src/eva2/server/go/operators/mutation/MutateGAGISwapBits.java
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
package eva2.server.go.operators.mutation;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.BitSet;
|
||||||
|
|
||||||
|
import eva2.gui.BeanInspector;
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGAIndividual;
|
||||||
|
import eva2.server.go.individuals.InterfaceGIIndividual;
|
||||||
|
import eva2.server.go.populations.Population;
|
||||||
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
import eva2.tools.math.RNG;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swap random pairs of values of a GA/GI individual. If preferPairs is true, unequal pairs
|
||||||
|
* are picked with some preference (by trying for l/2 times, where l is the binary
|
||||||
|
* individual length).
|
||||||
|
* A range of number of par mutations can be given from which the actual number of pairs
|
||||||
|
* is drawn in a uniform way.
|
||||||
|
*
|
||||||
|
* User: streiche, mkron
|
||||||
|
* Date: 05.08.2004
|
||||||
|
* Time: 17:45:36
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
public class MutateGAGISwapBits implements InterfaceMutation, java.io.Serializable {
|
||||||
|
private int minNumMutations = 1;
|
||||||
|
private int maxNumMutations = 3;
|
||||||
|
private boolean preferTrueChange = true; // if true, pairs of (1,0) are swapped with higher probability
|
||||||
|
|
||||||
|
public MutateGAGISwapBits() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutateGAGISwapBits(MutateGAGISwapBits mutator) {
|
||||||
|
minNumMutations = mutator.minNumMutations;
|
||||||
|
maxNumMutations = mutator.maxNumMutations;
|
||||||
|
this.setPreferTrueChange(mutator.isPreferTrueChange());
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutateGAGISwapBits(int minMutations, int maxMutations, boolean preferTrueChange) {
|
||||||
|
minNumMutations = minMutations;
|
||||||
|
maxNumMutations = maxMutations;
|
||||||
|
this.preferTrueChange = preferTrueChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method will enable you to clone a given mutation operator
|
||||||
|
* @return The clone
|
||||||
|
*/
|
||||||
|
public Object clone() {
|
||||||
|
return new MutateGAGISwapBits(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to evaluate wether two mutation operators
|
||||||
|
* are actually the same.
|
||||||
|
* @param mutator The other mutation operator
|
||||||
|
*/
|
||||||
|
public boolean equals(Object mutator) {
|
||||||
|
if (mutator instanceof MutateGAGISwapBits) {
|
||||||
|
MutateGAGISwapBits mut = (MutateGAGISwapBits)mutator;
|
||||||
|
if (this.minNumMutations != mut.minNumMutations) return false;
|
||||||
|
if (this.maxNumMutations != mut.maxNumMutations) return false;
|
||||||
|
return true;
|
||||||
|
} else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to init the mutation operator
|
||||||
|
* @param individual The individual that will be mutated.
|
||||||
|
* @param opt The optimization problem.
|
||||||
|
*/
|
||||||
|
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to perform either crossover on the strategy parameters
|
||||||
|
* or to deal in some other way with the crossover event.
|
||||||
|
* @param indy1 The original mother
|
||||||
|
* @param partners The original partners
|
||||||
|
*/
|
||||||
|
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1, Population partners) {
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method will mutate a given AbstractEAIndividual. If the individual
|
||||||
|
* doesn't implement InterfaceGAIndividual or InterfaceGIIndividual nothing happens.
|
||||||
|
* @param individual The individual that is to be mutated
|
||||||
|
*/
|
||||||
|
public void mutate(AbstractEAIndividual individual) {
|
||||||
|
// System.err.println("Before Mutate: " +(individual.getStringRepresentation()));
|
||||||
|
if (individual instanceof InterfaceGAIndividual || (individual instanceof InterfaceGIIndividual)) {
|
||||||
|
Object genotype = null;
|
||||||
|
int genoLen=-1;
|
||||||
|
if (individual instanceof InterfaceGAIndividual) {
|
||||||
|
genotype = ((InterfaceGAIndividual)individual).getBGenotype();
|
||||||
|
genoLen = ((InterfaceGAIndividual)individual).getGenotypeLength();
|
||||||
|
} else {
|
||||||
|
genotype = ((InterfaceGIIndividual)individual).getIGenotype();
|
||||||
|
genoLen =((InterfaceGIIndividual)individual).getGenotypeLength();
|
||||||
|
}
|
||||||
|
int[][] mutationIndices = selectMutationIndices(genoLen, genotype);
|
||||||
|
// System.err.println("Indices are " + BeanInspector.toString(mutationIndices));
|
||||||
|
// double instances of mutationIndices could be checked here... *sigh*
|
||||||
|
for (int i = 0; i < mutationIndices.length; i++) {
|
||||||
|
Object tmp = valueAt(genotype, mutationIndices[i][1]);
|
||||||
|
setValueAt(genotype, mutationIndices[i][1], valueAt(genotype, mutationIndices[i][0]));
|
||||||
|
setValueAt(genotype, mutationIndices[i][0], tmp);
|
||||||
|
// tmpBit = tmpBitSet.get(mutationIndices[i][1]);
|
||||||
|
// tmpBitSet.set(mutationIndices[i][1], tmpBitSet.get(mutationIndices[i][0]));
|
||||||
|
// tmpBitSet.set(mutationIndices[i][0], tmpBit);
|
||||||
|
}
|
||||||
|
if (genotype instanceof BitSet) ((InterfaceGAIndividual)individual).SetBGenotype((BitSet)genotype);
|
||||||
|
else ((InterfaceGIIndividual)individual).SetIGenotype((int[])genotype);
|
||||||
|
}
|
||||||
|
// System.err.println("After Mutate: " +(individual.getStringRepresentation()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the mutation indices for the current mutation operation.
|
||||||
|
*
|
||||||
|
* @param genoLen
|
||||||
|
* @param genotype
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected int[][] selectMutationIndices(int genoLen, Object genotype) {
|
||||||
|
int numMutes = RNG.randomInt(minNumMutations, maxNumMutations);
|
||||||
|
int[][] mutationIndices = new int[numMutes][2];
|
||||||
|
for (int i = 0; i < mutationIndices.length; i++) {
|
||||||
|
mutationIndices[i][0] = getRandomIndex(genoLen, genotype, -1); // may prefer true bits
|
||||||
|
mutationIndices[i][1] = getRandomIndex(genoLen, genotype, mutationIndices[i][0]); // may prefer false bits
|
||||||
|
}
|
||||||
|
return mutationIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setValueAt(Object genotype, int i, Object val) {
|
||||||
|
if (genotype instanceof BitSet) ((BitSet)genotype).set(i, (Boolean)val);
|
||||||
|
else ((int[])genotype)[i]=(Integer)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getRandomIndex(int genoLen, Object genotype, int lastIndex) {
|
||||||
|
return getRandomIndex(genoLen/2, genotype, (lastIndex>=0) ? (valueAt(genotype, lastIndex)) : null, 0, genoLen-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a random index within the given genotype lying in [iMin,iMax]. If applicable, the given
|
||||||
|
* value is avoided with certain probility, namely by trying to find a different value for maxTries
|
||||||
|
* times.
|
||||||
|
*
|
||||||
|
* @param maxTries
|
||||||
|
* @param genotype
|
||||||
|
* @param maybePreferedValue
|
||||||
|
* @param iMin
|
||||||
|
* @param iMax
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected int getRandomIndex(int maxTries, Object genotype, Object avoidValue, int iMin, int iMax) {
|
||||||
|
int k = RNG.randomInt(iMin, iMax);
|
||||||
|
if (isPreferTrueChange() && avoidValue!=null) {
|
||||||
|
while ((avoidValue==valueAt(genotype, k)) && (maxTries>=0)) {
|
||||||
|
k = RNG.randomInt(iMin, iMax); // try next random position
|
||||||
|
maxTries--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
// private int getRandomSecondIndex(int firstIndex, AbstractEAIndividual individual) {
|
||||||
|
// int genoLen = ((InterfaceGAIndividual)individual).getGenotypeLength();
|
||||||
|
// return RNG.randomInt(0, genoLen);
|
||||||
|
// }
|
||||||
|
|
||||||
|
protected Object valueAt(Object genotype, int k) {
|
||||||
|
if (genotype instanceof BitSet) return ((BitSet)genotype).get(k);
|
||||||
|
else return ((int[])genotype)[k];
|
||||||
|
}
|
||||||
|
/** This method allows you to get a string representation of the mutation
|
||||||
|
* operator
|
||||||
|
* @return A descriptive string.
|
||||||
|
*/
|
||||||
|
public String getStringRepresentation() {
|
||||||
|
return "GA/GI swap values mutation";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************************************************************************************
|
||||||
|
* These are for GUI
|
||||||
|
*/
|
||||||
|
/** This method allows the CommonJavaObjectEditorPanel to read the
|
||||||
|
* name to the current object.
|
||||||
|
* @return The name.
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return "GA-GI swap bits mutation";
|
||||||
|
}
|
||||||
|
/** This method returns a global info string
|
||||||
|
* @return description
|
||||||
|
*/
|
||||||
|
public static String globalInfo() {
|
||||||
|
return "This mutation operator swaps n random position pairs (bits or integers). The number of mutations is" +
|
||||||
|
" chosen uniformly in a given interval.";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This method allows you to set the number of mutations that occur in the
|
||||||
|
* genotype.
|
||||||
|
* @param mutations The number of mutations.
|
||||||
|
*/
|
||||||
|
public void setMinNumberOfMutations(int mutations) {
|
||||||
|
if (mutations < 0) mutations = 0;
|
||||||
|
this.minNumMutations = mutations;
|
||||||
|
}
|
||||||
|
public int getMinNumberOfMutations() {
|
||||||
|
return this.minNumMutations;
|
||||||
|
}
|
||||||
|
public String minNumberOfMutationsTipText() {
|
||||||
|
return "The minimum number of values to be swapped.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxNumberOfMutations(int mutations) {
|
||||||
|
if (mutations < 0) mutations = 0;
|
||||||
|
this.maxNumMutations = mutations;
|
||||||
|
}
|
||||||
|
public int getMaxNumberOfMutations() {
|
||||||
|
return this.maxNumMutations;
|
||||||
|
}
|
||||||
|
public String maxNumberOfMutationsTipText() {
|
||||||
|
return "The maximum number of values to be swapped.";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPreferTrueChange(boolean preferPairs) {
|
||||||
|
this.preferTrueChange = preferPairs;
|
||||||
|
}
|
||||||
|
public boolean isPreferTrueChange() {
|
||||||
|
return preferTrueChange;
|
||||||
|
}
|
||||||
|
public String preferTrueChangeTipText() {
|
||||||
|
return "If set to true, mutation events will prefer swapping non-equal values";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package eva2.server.go.operators.mutation;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import eva2.tools.EVAERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation restricts the swap positions of the standard swapping mutation
|
||||||
|
* to swaps within subsequences (segments) of the genotype. The segments have a fixed length.
|
||||||
|
*
|
||||||
|
* @author mkron
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MutateGAGISwapBitsSegmentwise extends MutateGAGISwapBits implements Serializable {
|
||||||
|
private int segmentLength = 8;
|
||||||
|
|
||||||
|
public MutateGAGISwapBitsSegmentwise() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutateGAGISwapBitsSegmentwise(MutateGAGISwapBitsSegmentwise mutator) {
|
||||||
|
super(mutator);
|
||||||
|
segmentLength = mutator.segmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutateGAGISwapBitsSegmentwise(int segmentLength) {
|
||||||
|
this();
|
||||||
|
this.segmentLength = segmentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MutateGAGISwapBitsSegmentwise(int segmentLen, int minMutations, int maxMutations, boolean preferTrueChange) {
|
||||||
|
super(minMutations, maxMutations, preferTrueChange);
|
||||||
|
this.segmentLength = segmentLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone() {
|
||||||
|
return new MutateGAGISwapBitsSegmentwise(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String globalInfo() {
|
||||||
|
return "Segment-wise swapping of elements - the mutation pairs are selected within the same" +
|
||||||
|
" subsequence of the genotype.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "GA-GI swap bits segment-wise mutation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getRandomIndex(int genoLen, Object genotype, int lastIndex) {
|
||||||
|
// restrict to the same segment of lastIndex if >= 0.
|
||||||
|
int iMin=0, iMax=genoLen-1; // default bounds
|
||||||
|
if (lastIndex>=0) {
|
||||||
|
// select same segment
|
||||||
|
iMin = segmentLength * ((int)(lastIndex/segmentLength));
|
||||||
|
iMax = iMin+segmentLength-1;
|
||||||
|
if (iMax>=genoLen) {
|
||||||
|
EVAERROR.errorMsgOnce("Warning, the last segment exceeds the genotype length (so it is not a multiple of the genotype length");
|
||||||
|
iMax=genoLen-1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.getRandomIndex(segmentLength/2, genotype, (lastIndex>=0) ? (valueAt(genotype, lastIndex)) : null,
|
||||||
|
iMin, iMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSegmentLength() {
|
||||||
|
return segmentLength;
|
||||||
|
}
|
||||||
|
public void setSegmentLength(int segmentLength) {
|
||||||
|
this.segmentLength = segmentLength;
|
||||||
|
}
|
||||||
|
public String segmentLengthTipText() {
|
||||||
|
return "The length of subsequences to which mutations are restricted";
|
||||||
|
}
|
||||||
|
}
|
@ -1,161 +0,0 @@
|
|||||||
package eva2.server.go.operators.mutation;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.BitSet;
|
|
||||||
|
|
||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
|
||||||
import eva2.server.go.individuals.InterfaceGAIndividual;
|
|
||||||
import eva2.server.go.populations.Population;
|
|
||||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
|
||||||
import eva2.tools.math.RNG;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swap two random bits of a GA individual. If preferPairs is true, unequal pairs
|
|
||||||
* are picked with some preference (by trying for l/2 times, where l is the binary
|
|
||||||
* individual length).
|
|
||||||
*
|
|
||||||
* User: streiche, mkron
|
|
||||||
* Date: 05.08.2004
|
|
||||||
* Time: 17:45:36
|
|
||||||
* To change this template use File | Settings | File Templates.
|
|
||||||
*/
|
|
||||||
public class MutateGASwapBits implements InterfaceMutation, java.io.Serializable {
|
|
||||||
private int m_NumberOfMutations = 1;
|
|
||||||
private boolean preferPairs = true; // if true, pairs of (1,0) are swapped with higher probability
|
|
||||||
|
|
||||||
public MutateGASwapBits() {
|
|
||||||
|
|
||||||
}
|
|
||||||
public MutateGASwapBits(MutateGASwapBits mutator) {
|
|
||||||
this.m_NumberOfMutations = mutator.m_NumberOfMutations;
|
|
||||||
this.setPreferTrueChange(mutator.isPreferTrueChange());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method will enable you to clone a given mutation operator
|
|
||||||
* @return The clone
|
|
||||||
*/
|
|
||||||
public Object clone() {
|
|
||||||
return new MutateGASwapBits(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to evaluate wether two mutation operators
|
|
||||||
* are actually the same.
|
|
||||||
* @param mutator The other mutation operator
|
|
||||||
*/
|
|
||||||
public boolean equals(Object mutator) {
|
|
||||||
if (mutator instanceof MutateGASwapBits) {
|
|
||||||
MutateGASwapBits mut = (MutateGASwapBits)mutator;
|
|
||||||
if (this.m_NumberOfMutations != mut.m_NumberOfMutations) return false;
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to init the mutation operator
|
|
||||||
* @param individual The individual that will be mutated.
|
|
||||||
* @param opt The optimization problem.
|
|
||||||
*/
|
|
||||||
public void init(AbstractEAIndividual individual, InterfaceOptimizationProblem opt) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to perform either crossover on the strategy parameters
|
|
||||||
* or to deal in some other way with the crossover event.
|
|
||||||
* @param indy1 The original mother
|
|
||||||
* @param partners The original partners
|
|
||||||
*/
|
|
||||||
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1, Population partners) {
|
|
||||||
// nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method will mutate a given AbstractEAIndividual. If the individual
|
|
||||||
* doesn't implement InterfaceGAIndividual nothing happens.
|
|
||||||
* @param individual The individual that is to be mutated
|
|
||||||
*/
|
|
||||||
public void mutate(AbstractEAIndividual individual) {
|
|
||||||
//System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
|
|
||||||
if (individual instanceof InterfaceGAIndividual) {
|
|
||||||
BitSet tmpBitSet = ((InterfaceGAIndividual)individual).getBGenotype();
|
|
||||||
int[][] mutationIndices = new int[this.m_NumberOfMutations][2];
|
|
||||||
boolean tmpBit;
|
|
||||||
for (int i = 0; i < mutationIndices.length; i++) {
|
|
||||||
mutationIndices[i][0] = getRandomIndex(individual, true); // may prefer true bits
|
|
||||||
mutationIndices[i][1] = getRandomIndex(individual, false); // may prefer false bits
|
|
||||||
}
|
|
||||||
// double instances of mutationIndices could be checked here... *sigh*
|
|
||||||
for (int i = 0; i < mutationIndices.length; i++) {
|
|
||||||
tmpBit = tmpBitSet.get(mutationIndices[i][1]);
|
|
||||||
tmpBitSet.set(mutationIndices[i][1], tmpBitSet.get(mutationIndices[i][0]));
|
|
||||||
tmpBitSet.set(mutationIndices[i][0], tmpBit);
|
|
||||||
}
|
|
||||||
((InterfaceGAIndividual)individual).SetBGenotype(tmpBitSet);
|
|
||||||
}
|
|
||||||
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getRandomIndex(AbstractEAIndividual individual, boolean maybePrefered) {
|
|
||||||
int genoLen = ((InterfaceGAIndividual)individual).getGenotypeLength();
|
|
||||||
int k = RNG.randomInt(0, genoLen);
|
|
||||||
if (isPreferTrueChange()) {
|
|
||||||
int maxTries=genoLen/2;
|
|
||||||
while (!(maybePrefered==((InterfaceGAIndividual)individual).getBGenotype().get(k)) && (maxTries>=0)) {
|
|
||||||
k=(k+RNG.randomInt(1,genoLen))%genoLen; // try next random position
|
|
||||||
maxTries--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private int getRandomSecondIndex(int firstIndex, AbstractEAIndividual individual) {
|
|
||||||
// int genoLen = ((InterfaceGAIndividual)individual).getGenotypeLength();
|
|
||||||
// return RNG.randomInt(0, genoLen);
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** This method allows you to get a string representation of the mutation
|
|
||||||
* operator
|
|
||||||
* @return A descriptive string.
|
|
||||||
*/
|
|
||||||
public String getStringRepresentation() {
|
|
||||||
return "GA swap bits mutation";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************************************
|
|
||||||
* These are for GUI
|
|
||||||
*/
|
|
||||||
/** This method allows the CommonJavaObjectEditorPanel to read the
|
|
||||||
* name to the current object.
|
|
||||||
* @return The name.
|
|
||||||
*/
|
|
||||||
public String getName() {
|
|
||||||
return "GA swap bits mutation";
|
|
||||||
}
|
|
||||||
/** This method returns a global info string
|
|
||||||
* @return description
|
|
||||||
*/
|
|
||||||
public static String globalInfo() {
|
|
||||||
return "This mutation operator swaps n random bits.";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This method allows you to set the number of mutations that occur in the
|
|
||||||
* genotype.
|
|
||||||
* @param mutations The number of mutations.
|
|
||||||
*/
|
|
||||||
public void setNumberOfMutations(int mutations) {
|
|
||||||
if (mutations < 0) mutations = 0;
|
|
||||||
this.m_NumberOfMutations = mutations;
|
|
||||||
}
|
|
||||||
public int getNumberOfMutations() {
|
|
||||||
return this.m_NumberOfMutations;
|
|
||||||
}
|
|
||||||
public String numberOfMutationsTipText() {
|
|
||||||
return "The number of bits to be swapped.";
|
|
||||||
}
|
|
||||||
public void setPreferTrueChange(boolean preferPairs) {
|
|
||||||
this.preferPairs = preferPairs;
|
|
||||||
}
|
|
||||||
public boolean isPreferTrueChange() {
|
|
||||||
return preferPairs;
|
|
||||||
}
|
|
||||||
public String preferTrueChangeTipText() {
|
|
||||||
return "If set to true, mutation events will prefer swapping 1 and 0";
|
|
||||||
}
|
|
||||||
}
|
|
@ -100,7 +100,7 @@ public class MutateGASwapBitsSegmentwise implements InterfaceMutation, java.io.S
|
|||||||
* @param individual The individual that is to be mutated
|
* @param individual The individual that is to be mutated
|
||||||
*/
|
*/
|
||||||
public void mutate(AbstractEAIndividual individual) {
|
public void mutate(AbstractEAIndividual individual) {
|
||||||
//System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
|
// System.out.println("Before Mutate: " +(individual).getStringRepresentation());
|
||||||
if (individual instanceof InterfaceGAIndividual) {
|
if (individual instanceof InterfaceGAIndividual) {
|
||||||
BitSet tmpBitSet = ((InterfaceGAIndividual)individual).getBGenotype();
|
BitSet tmpBitSet = ((InterfaceGAIndividual)individual).getBGenotype();
|
||||||
int genLen=((InterfaceGAIndividual)individual).getGenotypeLength();
|
int genLen=((InterfaceGAIndividual)individual).getGenotypeLength();
|
||||||
@ -122,7 +122,7 @@ public class MutateGASwapBitsSegmentwise implements InterfaceMutation, java.io.S
|
|||||||
}
|
}
|
||||||
((InterfaceGAIndividual)individual).SetBGenotype(tmpBitSet); // write back the genotype
|
((InterfaceGAIndividual)individual).SetBGenotype(tmpBitSet); // write back the genotype
|
||||||
}
|
}
|
||||||
//System.out.println("After Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
|
// System.out.println("After Mutate: " +(individual).getStringRepresentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -180,7 +180,8 @@ public class MutateGASwapBitsSegmentwise implements InterfaceMutation, java.io.S
|
|||||||
* @return description
|
* @return description
|
||||||
*/
|
*/
|
||||||
public static String globalInfo() {
|
public static String globalInfo() {
|
||||||
return "This mutation operator swaps bits in subsegments of the genotype.";
|
return "This mutation operator swaps bits in subsegments of the genotype. Each segment is mutated" +
|
||||||
|
" with a certain probability. Depending on the setting, multiple mutations per segment may occur.";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPreferTrueChange(boolean preferPairs) {
|
public void setPreferTrueChange(boolean preferPairs) {
|
||||||
|
@ -80,7 +80,7 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
|
|||||||
|
|
||||||
int parallelthreads = 1;
|
int parallelthreads = 1;
|
||||||
|
|
||||||
protected AbstractEAIndividual m_Template;
|
protected AbstractEAIndividual m_Template = null;
|
||||||
// private transient ArrayList<ParamChangeListener> changeListeners = null;
|
// private transient ArrayList<ParamChangeListener> changeListeners = null;
|
||||||
|
|
||||||
private double defaultAccuracy = 0.01; // default accuracy for identifying optima.
|
private double defaultAccuracy = 0.01; // default accuracy for identifying optima.
|
||||||
|
@ -20,7 +20,7 @@ public abstract class AbstractProblemInteger extends AbstractOptimizationProblem
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void initTemplate() {
|
protected void initTemplate() {
|
||||||
this.m_Template = new GAIndividualIntegerData();
|
if (m_Template==null) m_Template = new GAIndividualIntegerData();
|
||||||
if (((InterfaceDataTypeInteger)this.m_Template).size()!=this.getProblemDimension()) {
|
if (((InterfaceDataTypeInteger)this.m_Template).size()!=this.getProblemDimension()) {
|
||||||
((InterfaceDataTypeInteger)this.m_Template).setIntegerDataLength(this.getProblemDimension());
|
((InterfaceDataTypeInteger)this.m_Template).setIntegerDataLength(this.getProblemDimension());
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import java.util.BitSet;
|
|||||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
import eva2.server.go.individuals.InterfaceDataTypeBinary;
|
import eva2.server.go.individuals.InterfaceDataTypeBinary;
|
||||||
import eva2.server.go.operators.mutation.MutateEAMixer;
|
import eva2.server.go.operators.mutation.MutateEAMixer;
|
||||||
import eva2.server.go.operators.mutation.MutateGASwapBits;
|
import eva2.server.go.operators.mutation.MutateGAGISwapBits;
|
||||||
import eva2.server.go.operators.mutation.MutateGAUniform;
|
import eva2.server.go.operators.mutation.MutateGAUniform;
|
||||||
import eva2.server.go.strategies.InterfaceOptimizer;
|
import eva2.server.go.strategies.InterfaceOptimizer;
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ public class B1Problem extends AbstractProblemBinary implements java.io.Serializ
|
|||||||
|
|
||||||
public B1Problem() {
|
public B1Problem() {
|
||||||
super();
|
super();
|
||||||
this.getIndividualTemplate().setMutationOperator(new MutateEAMixer(new MutateGASwapBits(), new MutateGAUniform()));
|
this.getIndividualTemplate().setMutationOperator(new MutateEAMixer(new MutateGAGISwapBits(), new MutateGAUniform()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public B1Problem(B1Problem b) {
|
public B1Problem(B1Problem b) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user