Additional integer mutation operator
This commit is contained in:
@@ -10,11 +10,12 @@ import eva2.tools.EVAERROR;
|
||||
import eva2.tools.math.RNG;
|
||||
|
||||
/**
|
||||
* An initialization method which sets a fixed number of specified values per segment,
|
||||
* An initialization method which sets a fixed number of specified target elements 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
|
||||
* For binary individuals, this allows to control the number of bits per segment by
|
||||
* setting the target element to '1'. For
|
||||
* integer individuals, it allows to control the number of occurrences 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).
|
||||
*
|
||||
@@ -27,7 +28,6 @@ import eva2.tools.math.RNG;
|
||||
* has strict priority over the fixed cardinality definition.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class GAGIInitializeSegmentwise implements InterfaceInitialization, java.io.Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -178,24 +178,24 @@ public class GAGIInitializeSegmentwise implements InterfaceInitialization, java.
|
||||
else return (targetElement!=1);
|
||||
}
|
||||
|
||||
public int[] getBitsPerSegmentArray() {
|
||||
public int[] getTargetElementsPerSegmentArray() {
|
||||
return bitsPerSegmentArray;
|
||||
}
|
||||
public void setBitsPerSegmentArray(int[] bitsPerSegmentArray) {
|
||||
public void setTargetElementsPerSegmentArray(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 String targetElementsPerSegmentArrayTipText() {
|
||||
return "A value per segment defining the number of target elements to set for that segment, or null if fixed";
|
||||
}
|
||||
|
||||
public int getBitsPerSegment() {
|
||||
public int getTargetElementsPerSegment() {
|
||||
return bitsPerSegment;
|
||||
}
|
||||
public void setBitsPerSegment(int bitsPerSegment) {
|
||||
public void setTargetElementsPerSegment(int bitsPerSegment) {
|
||||
this.bitsPerSegment = bitsPerSegment;
|
||||
}
|
||||
public String bitsPerSegmentTipText() {
|
||||
return "If not array-wise defined, this fixed number of bits is set per segment";
|
||||
public String targetElementsPerSegmentTipText() {
|
||||
return "If not defined as an array, this fixed number of target elements is set per segment";
|
||||
}
|
||||
|
||||
public int getSegmentLength() {
|
||||
|
164
src/eva2/server/go/operators/mutation/MutateGISubset.java
Normal file
164
src/eva2/server/go/operators/mutation/MutateGISubset.java
Normal file
@@ -0,0 +1,164 @@
|
||||
package eva2.server.go.operators.mutation;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceGIIndividual;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
import eva2.tools.EVAERROR;
|
||||
import eva2.tools.math.RNG;
|
||||
|
||||
/**
|
||||
* An integer mutation operator which switches elements within a given subset only.
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
*/
|
||||
public class MutateGISubset implements InterfaceMutation, Serializable {
|
||||
private int[] mutableSet = new int[]{0,1};
|
||||
private int minNumMutations = 1;
|
||||
private int maxNumMutations = 3;
|
||||
private boolean enforceMutablePositions = true;
|
||||
|
||||
public MutateGISubset() {}
|
||||
|
||||
public MutateGISubset(MutateGISubset o) {
|
||||
this.minNumMutations = o.minNumMutations;
|
||||
this.maxNumMutations = o.maxNumMutations;
|
||||
this.enforceMutablePositions = o.enforceMutablePositions;
|
||||
if (o.mutableSet!=null) {
|
||||
this.mutableSet=new int[o.mutableSet.length];
|
||||
System.arraycopy(o.mutableSet, 0, this.mutableSet, 0, o.mutableSet.length);
|
||||
}
|
||||
}
|
||||
|
||||
public MutateGISubset(int[] muteSet, int minMutes, int maxMutes) {
|
||||
setMutableSet(muteSet);
|
||||
setMinNumMutations(minMutes);
|
||||
setMaxNumMutations(maxMutes);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new MutateGISubset(this);
|
||||
}
|
||||
|
||||
public void crossoverOnStrategyParameters(AbstractEAIndividual indy1,
|
||||
Population partners) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
public String getStringRepresentation() {
|
||||
return "GI subset mutation in " + BeanInspector.toString(mutableSet);
|
||||
}
|
||||
|
||||
public void init(AbstractEAIndividual individual,
|
||||
InterfaceOptimizationProblem opt) {
|
||||
// nothing to do
|
||||
|
||||
}
|
||||
|
||||
public void mutate(AbstractEAIndividual individual) {
|
||||
if (individual instanceof InterfaceGIIndividual) {
|
||||
InterfaceGIIndividual giIndy = (InterfaceGIIndividual)individual;
|
||||
int[] genotype = giIndy.getIGenotype();
|
||||
int[][] range = giIndy.getIntRange();
|
||||
int numMutes=RNG.randomInt(minNumMutations, maxNumMutations);
|
||||
for (int i=0; i<numMutes; i++) {
|
||||
maybePerformSingleMutation(genotype, range, genotype.length/numMutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void maybePerformSingleMutation(int[] genotype, int[][] range, int maxTries) {
|
||||
int index=RNG.randomInt(genotype.length);
|
||||
if (enforceMutablePositions && !(isMutable(genotype[index]))) {
|
||||
// if the mutation event should be forced, search a mutable element with a max. no. tries
|
||||
do {
|
||||
index=RNG.randomInt(genotype.length);
|
||||
maxTries--;
|
||||
} while (maxTries>0 && (!isMutable(genotype[index])));
|
||||
}
|
||||
if (isMutable(genotype[index])) { // if it is in the mutable subset
|
||||
genotype[index]=randomValidElement(range, index, genotype[index]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a randomly chosen element of the mutable subset lying in the range
|
||||
* or the old value if the randomly chosen value
|
||||
* @param range
|
||||
* @param index
|
||||
* @param oldVal
|
||||
* @return
|
||||
*/
|
||||
private int randomValidElement(int[][] range, int index, int oldVal) {
|
||||
int v = mutableSet[RNG.randomInt(mutableSet.length)];
|
||||
if (v>=range[index][0] && (v<=range[index][1])) return v;
|
||||
else {
|
||||
EVAERROR.errorMsgOnce("Warning, mutation subset violates range definition!");
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given value is member of the mutable subset, otherwise false.
|
||||
* @param v
|
||||
* @return
|
||||
*/
|
||||
private boolean isMutable(int v) {
|
||||
for (int i=0; i<mutableSet.length; i++) {
|
||||
if (mutableSet[i]==v) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String globalInfo() {
|
||||
return "A mutation operator which switches positions within a given subset only. A random " +
|
||||
"position is chosen but mutated only if its allele is contained" +
|
||||
" in the mutable set. The new allele is chosen from this set as well." +
|
||||
" In case the random positions do not contain a mutable allele, the switching is skipped. " +
|
||||
"This means that fewer switches may occur than expected from the minimal bound.";
|
||||
}
|
||||
|
||||
public int[] getMutableSet() {
|
||||
return mutableSet;
|
||||
}
|
||||
public void setMutableSet(int[] mutationSubset) {
|
||||
this.mutableSet = mutationSubset;
|
||||
}
|
||||
public String mutableSetTipText() {
|
||||
return "A subset of integers among which mutations may occur.";
|
||||
}
|
||||
|
||||
public int getMinNumMutations() {
|
||||
return minNumMutations;
|
||||
}
|
||||
public void setMinNumMutations(int minNumMutations) {
|
||||
this.minNumMutations = minNumMutations;
|
||||
}
|
||||
public String minNumMutationsTipText() {
|
||||
return "A lower bound for the number of positions changed per mutation event";
|
||||
}
|
||||
|
||||
public int getMaxNumMutations() {
|
||||
return maxNumMutations;
|
||||
}
|
||||
public void setMaxNumMutations(int maxNumMutations) {
|
||||
this.maxNumMutations = maxNumMutations;
|
||||
}
|
||||
public String maxNumMutationsTipText() {
|
||||
return "An upper bound for the number of positions changed per mutation event";
|
||||
}
|
||||
|
||||
public boolean isEnforceMutablePositions() {
|
||||
return enforceMutablePositions;
|
||||
}
|
||||
public void setEnforceMutablePositions(boolean enforceMutablePositions) {
|
||||
this.enforceMutablePositions = enforceMutablePositions;
|
||||
}
|
||||
public String enforceMutablePositionsTipText() {
|
||||
return "If true, the probability to hit a mutable position in a mutation event is increased by trying multiple times.";
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user