From 9dfcf4d71a1fd7b3d99fe4b8dd209e71742c0ac2 Mon Sep 17 00:00:00 2001 From: Marcel Kronfeld Date: Thu, 27 Jan 2011 10:02:10 +0000 Subject: [PATCH] Additional integer mutation operator --- .../GAGIInitializeSegmentwise.java | 24 +-- .../go/operators/mutation/MutateGISubset.java | 164 ++++++++++++++++++ 2 files changed, 176 insertions(+), 12 deletions(-) create mode 100644 src/eva2/server/go/operators/mutation/MutateGISubset.java diff --git a/src/eva2/server/go/operators/initialization/GAGIInitializeSegmentwise.java b/src/eva2/server/go/operators/initialization/GAGIInitializeSegmentwise.java index ef201248..51eae204 100644 --- a/src/eva2/server/go/operators/initialization/GAGIInitializeSegmentwise.java +++ b/src/eva2/server/go/operators/initialization/GAGIInitializeSegmentwise.java @@ -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() { diff --git a/src/eva2/server/go/operators/mutation/MutateGISubset.java b/src/eva2/server/go/operators/mutation/MutateGISubset.java new file mode 100644 index 00000000..f866da31 --- /dev/null +++ b/src/eva2/server/go/operators/mutation/MutateGISubset.java @@ -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; i0 && (!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