Added an abstraction over individual initialization methods.
This commit is contained in:
parent
d357bbfe98
commit
726a3cc6bf
@ -13,6 +13,8 @@ import eva2.server.go.individuals.codings.gp.InterfaceProgram;
|
|||||||
import eva2.server.go.operators.constraint.InterfaceConstraint;
|
import eva2.server.go.operators.constraint.InterfaceConstraint;
|
||||||
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
import eva2.server.go.operators.crossover.InterfaceCrossover;
|
||||||
import eva2.server.go.operators.crossover.NoCrossover;
|
import eva2.server.go.operators.crossover.NoCrossover;
|
||||||
|
import eva2.server.go.operators.initialization.DefaultInitialization;
|
||||||
|
import eva2.server.go.operators.initialization.InterfaceInitialization;
|
||||||
import eva2.server.go.operators.mutation.InterfaceMutation;
|
import eva2.server.go.operators.mutation.InterfaceMutation;
|
||||||
import eva2.server.go.operators.mutation.NoMutation;
|
import eva2.server.go.operators.mutation.NoMutation;
|
||||||
import eva2.server.go.populations.Population;
|
import eva2.server.go.populations.Population;
|
||||||
@ -58,7 +60,9 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
|||||||
protected double m_MutationProbability = 0.2;
|
protected double m_MutationProbability = 0.2;
|
||||||
protected InterfaceMutation m_MutationOperator = new NoMutation();
|
protected InterfaceMutation m_MutationOperator = new NoMutation();
|
||||||
protected InterfaceCrossover m_CrossoverOperator = new NoCrossover();
|
protected InterfaceCrossover m_CrossoverOperator = new NoCrossover();
|
||||||
// protected String[] m_Identifiers = new String[m_ObjectIncrement];
|
protected InterfaceInitialization m_InitOperator = new DefaultInitialization();
|
||||||
|
|
||||||
|
// protected String[] m_Identifiers = new String[m_ObjectIncrement];
|
||||||
// protected Object[] m_Objects = new Object[m_ObjectIncrement];
|
// protected Object[] m_Objects = new Object[m_ObjectIncrement];
|
||||||
protected HashMap<String,Object> m_dataHash = new HashMap<String,Object>();
|
protected HashMap<String,Object> m_dataHash = new HashMap<String,Object>();
|
||||||
|
|
||||||
@ -148,6 +152,7 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
|||||||
m_Marked = individual.m_Marked;
|
m_Marked = individual.m_Marked;
|
||||||
m_isPenalized = individual.m_isPenalized;
|
m_isPenalized = individual.m_isPenalized;
|
||||||
individualIndex = individual.individualIndex;
|
individualIndex = individual.individualIndex;
|
||||||
|
m_InitOperator = individual.m_InitOperator.clone();
|
||||||
if (individual.parentIDs != null) {
|
if (individual.parentIDs != null) {
|
||||||
parentIDs = new Long[individual.parentIDs.length];
|
parentIDs = new Long[individual.parentIDs.length];
|
||||||
System.arraycopy(individual.parentIDs, 0, parentIDs, 0, parentIDs.length);
|
System.arraycopy(individual.parentIDs, 0, parentIDs, 0, parentIDs.length);
|
||||||
@ -271,7 +276,8 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
|||||||
* @param opt The optimization problem that is to be solved.
|
* @param opt The optimization problem that is to be solved.
|
||||||
*/
|
*/
|
||||||
public void init(InterfaceOptimizationProblem opt) {
|
public void init(InterfaceOptimizationProblem opt) {
|
||||||
this.defaultInit(opt);
|
m_InitOperator.initialize(this, opt);
|
||||||
|
// this.defaultInit(opt);
|
||||||
this.m_MutationOperator.init(this, opt);
|
this.m_MutationOperator.init(this, opt);
|
||||||
this.m_CrossoverOperator.init(this, opt);
|
this.m_CrossoverOperator.init(this, opt);
|
||||||
}
|
}
|
||||||
@ -815,6 +821,16 @@ public abstract class AbstractEAIndividual implements IndividualInterface, java.
|
|||||||
return "The chance that crossover occurs.";
|
return "The chance that crossover occurs.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InterfaceInitialization getInitOperator() {
|
||||||
|
return m_InitOperator;
|
||||||
|
}
|
||||||
|
public void setInitOperator(InterfaceInitialization mInitOperator) {
|
||||||
|
m_InitOperator = mInitOperator;
|
||||||
|
}
|
||||||
|
public String initOperatorTipText() {
|
||||||
|
return "An initialization method for the individual";
|
||||||
|
}
|
||||||
|
|
||||||
/** This method allows you to store an arbitrary value under an arbitrary
|
/** This method allows you to store an arbitrary value under an arbitrary
|
||||||
* name.
|
* name.
|
||||||
* @param name The identifying name.
|
* @param name The identifying name.
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package eva2.server.go.operators.initialization;
|
||||||
|
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A dummy initialization method which only calls the default init method of the individual.
|
||||||
|
*
|
||||||
|
* @author mkron
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DefaultInitialization implements InterfaceInitialization, java.io.Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public DefaultInitialization() {}
|
||||||
|
|
||||||
|
public void initialize(AbstractEAIndividual indy, InterfaceOptimizationProblem problem) {
|
||||||
|
indy.defaultInit(problem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InterfaceInitialization clone() {
|
||||||
|
return new DefaultInitialization();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return "DefaultInitialization";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String globalInfo() {
|
||||||
|
return "Uses the standard initialization of the individual implementation";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,125 @@
|
|||||||
|
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.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// write back the genotype (it may have been cloned, who knows...)
|
||||||
|
gaIndy.SetBGenotype(genotype);
|
||||||
|
} 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], bitsPerSegment);
|
||||||
|
for (int k=(s)*bitsPerSegment; k<(s+1)*bitsPerSegment; k++) {
|
||||||
|
if (k<genotypeLen) genotype.set(k, nextSeg.get(k-(s*bitsPerSegment)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package eva2.server.go.operators.initialization;
|
||||||
|
|
||||||
|
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||||
|
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstraction over individual initialization methods in analogy
|
||||||
|
* to mutation and crossover. It is member of every abstract individual
|
||||||
|
* but the specific implementation may depend on the data type of the
|
||||||
|
* individual.
|
||||||
|
*
|
||||||
|
* @author mkron
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface InterfaceInitialization {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform initialization of a given individual, which may potentially depend on
|
||||||
|
* a problem instance.
|
||||||
|
*
|
||||||
|
* @param indy the target individual to initialize
|
||||||
|
* @param problem the problem instance under consideration
|
||||||
|
*/
|
||||||
|
public void initialize(AbstractEAIndividual indy, InterfaceOptimizationProblem problem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A specific cloning method.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public InterfaceInitialization clone();
|
||||||
|
}
|
@ -4,6 +4,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
import eva2.tools.EVAERROR;
|
||||||
|
|
||||||
|
|
||||||
public class RNG {
|
public class RNG {
|
||||||
private static Random random;
|
private static Random random;
|
||||||
@ -289,6 +291,10 @@ public class RNG {
|
|||||||
* Create a random bitset with given cardinality and lengths,
|
* Create a random bitset with given cardinality and lengths,
|
||||||
*/
|
*/
|
||||||
public static BitSet randomBitSet(int cardinality, int length) {
|
public static BitSet randomBitSet(int cardinality, int length) {
|
||||||
|
if (cardinality>length) {
|
||||||
|
EVAERROR.errorMsgOnce("Error, invalid cardinality " + cardinality + " requested for bit length "+ length +", cardinality will be reduced.");
|
||||||
|
cardinality=length;
|
||||||
|
}
|
||||||
BitSet bs = new BitSet(length);
|
BitSet bs = new BitSet(length);
|
||||||
int[] perm = randomPerm(length);
|
int[] perm = randomPerm(length);
|
||||||
for (int i=0; i<cardinality; i++) {
|
for (int i=0; i<cardinality; i++) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user