New GI operators (mutation, crossover) and adaptions

This commit is contained in:
Marcel Kronfeld 2011-01-25 10:16:30 +00:00
parent a207014610
commit 628499aab9
18 changed files with 848 additions and 483 deletions

View File

@ -32,7 +32,7 @@ import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.ESIndividualDoubleData;
import eva2.server.go.individuals.GAIndividualDoubleData;
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.MutateESFixedStepSize;
import eva2.server.go.operators.mutation.MutateESLocal;
@ -322,7 +322,7 @@ public class GOStandaloneVersion implements InterfaceGOStandalone, InterfacePopu
this.m_GO.getOptimizer().getPopulation().setTargetSize(100);
F1Problem problem = new F1Problem();
tmpIndy = new GAIndividualDoubleData();
((GAIndividualDoubleData)tmpIndy).setCrossoverOperator(new CrossoverGANPoint());
((GAIndividualDoubleData)tmpIndy).setCrossoverOperator(new CrossoverGAGINPoint());
((GAIndividualDoubleData)tmpIndy).setCrossoverProbability(1.0);
((GAIndividualDoubleData)tmpIndy).setMutationProbability(1.0);
((F1Problem)problem).setEAIndividual(tmpIndy);

View File

@ -3,7 +3,7 @@ package eva2.server.go.individuals;
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.mutation.InterfaceMutation;
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_MutationOperator = new MutateGANBit();
this.m_CrossoverProbability = 1.0;
this.m_CrossoverOperator = new CrossoverGANPoint();
this.m_CrossoverOperator = new CrossoverGAGINPoint();
this.m_GenotypeLength = 20;
this.m_Genotype = new BitSet();
}

View File

@ -5,7 +5,7 @@ import java.util.BitSet;
import eva2.server.go.individuals.codings.ga.GAStandardCodingDouble;
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.mutation.InterfaceMutation;
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_MutationOperator = new MutateGAUniform();
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[0][0] = -10;
this.m_Range[0][1] = 10;

View File

@ -5,7 +5,7 @@ import java.util.BitSet;
import eva2.server.go.individuals.codings.ga.GAStandardCodingInteger;
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.MutateGANBit;
import eva2.server.go.problems.InterfaceOptimizationProblem;
@ -31,7 +31,7 @@ public class GAIndividualIntegerData extends AbstractEAIndividual implements Int
this.m_MutationProbability = 0.2;
this.m_MutationOperator = new MutateGANBit();
this.m_CrossoverProbability = 0.7;
this.m_CrossoverOperator = new CrossoverGANPoint();
this.m_CrossoverOperator = new CrossoverGAGINPoint();
this.m_Range = new int[1][2];
this.m_CodingLenghts = new int[1];
this.m_CodingLenghts[0] = 3;

View File

@ -33,6 +33,11 @@ public class GIIndividualIntegerData extends AbstractEAIndividual implements Int
this.m_Genotype = new int[10];
}
public GIIndividualIntegerData(int[][] theRange) {
this();
SetIntRange(theRange);
}
public GIIndividualIntegerData(GIIndividualIntegerData individual) {
if (individual.m_Phenotype != null) {
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) {
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.m_Range.length + "!\n Use method setDoubleDataLength first!");
this.setIntegerDataLength(range.length);
}
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][1] = range[i][1];
}
this.setIntegerDataLength(range.length);
}
/** This method will return the range for all double attributes.

View File

@ -23,7 +23,7 @@ public interface InterfaceGIIndividual {
/** 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
* for dimension d.
* for dimension d where both are included.
* @param range The new range for the int data.
*/
public void SetIntRange(int[][] range);

View 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.";
}
}

View File

@ -10,31 +10,31 @@ import eva2.tools.math.RNG;
* @author mkron
*
*/
public class CrossoverGANPointSegmentwise extends CrossoverGANPoint {
public class CrossoverGAGINPointSegmentwise extends CrossoverGAGINPoint {
int segmentLength=8;
public CrossoverGANPointSegmentwise() {
public CrossoverGAGINPointSegmentwise() {
super();
}
public CrossoverGANPointSegmentwise(CrossoverGANPointSegmentwise o) {
public CrossoverGAGINPointSegmentwise(CrossoverGAGINPointSegmentwise o) {
super(o);
this.segmentLength=o.segmentLength;
}
public CrossoverGANPointSegmentwise(int nPoints, int segmentLen) {
public CrossoverGAGINPointSegmentwise(int nPoints, int segmentLen) {
super(nPoints);
setSegmentLength(segmentLen);
}
public Object clone() {
return new CrossoverGANPointSegmentwise(this);
return new CrossoverGAGINPointSegmentwise(this);
}
@Override
public boolean equals(Object crossover) {
if (super.equals(crossover) && (crossover instanceof CrossoverGANPointSegmentwise)) {
return ((CrossoverGANPointSegmentwise)crossover).segmentLength==this.segmentLength;
if (super.equals(crossover) && (crossover instanceof CrossoverGAGINPointSegmentwise)) {
return ((CrossoverGAGINPointSegmentwise)crossover).segmentLength==this.segmentLength;
} else return false;
}
@ -50,7 +50,7 @@ public class CrossoverGANPointSegmentwise extends CrossoverGANPoint {
}
public String getName() {
return "GA N-Point segment-wise crossover";
return "GA-GI N-Point segment-wise crossover";
}
public static String globalInfo() {

View File

@ -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.";
}
}

View File

@ -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.";
}
}

View File

@ -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";
}
}

View 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";
}
}

View File

@ -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";
}
}

View File

@ -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";
}
}

View File

@ -100,7 +100,7 @@ public class MutateGASwapBitsSegmentwise implements InterfaceMutation, java.io.S
* @param individual The individual that is to be mutated
*/
public void mutate(AbstractEAIndividual individual) {
//System.out.println("Before Mutate: " +((GAIndividual)individual).getSolutionRepresentationFor());
// System.out.println("Before Mutate: " +(individual).getStringRepresentation());
if (individual instanceof InterfaceGAIndividual) {
BitSet tmpBitSet = ((InterfaceGAIndividual)individual).getBGenotype();
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
}
//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
*/
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) {

View File

@ -80,7 +80,7 @@ implements InterfaceOptimizationProblem /*, InterfaceParamControllable*/, Serial
int parallelthreads = 1;
protected AbstractEAIndividual m_Template;
protected AbstractEAIndividual m_Template = null;
// private transient ArrayList<ParamChangeListener> changeListeners = null;
private double defaultAccuracy = 0.01; // default accuracy for identifying optima.

View File

@ -20,7 +20,7 @@ public abstract class AbstractProblemInteger extends AbstractOptimizationProblem
}
protected void initTemplate() {
this.m_Template = new GAIndividualIntegerData();
if (m_Template==null) m_Template = new GAIndividualIntegerData();
if (((InterfaceDataTypeInteger)this.m_Template).size()!=this.getProblemDimension()) {
((InterfaceDataTypeInteger)this.m_Template).setIntegerDataLength(this.getProblemDimension());
}

View File

@ -6,7 +6,7 @@ import java.util.BitSet;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.InterfaceDataTypeBinary;
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.strategies.InterfaceOptimizer;
@ -22,7 +22,7 @@ public class B1Problem extends AbstractProblemBinary implements java.io.Serializ
public B1Problem() {
super();
this.getIndividualTemplate().setMutationOperator(new MutateEAMixer(new MutateGASwapBits(), new MutateGAUniform()));
this.getIndividualTemplate().setMutationOperator(new MutateEAMixer(new MutateGAGISwapBits(), new MutateGAUniform()));
}
public B1Problem(B1Problem b) {