Adding new initialization method for binary individuals with certain cardinality

This commit is contained in:
Marcel Kronfeld 2010-12-09 12:47:57 +00:00
parent 91a0642e5d
commit 5fbe8eb5ed
7 changed files with 143 additions and 34 deletions

View File

@ -614,6 +614,24 @@ public class BeanInspector {
return false;
}
/**
* Get the primitive class of a Java primitive encapsulation, or null if not applicable.
* E.g., returns int for Integer, long for Long, Boolean for Boolean etc.
*
* @param cls
* @return
*/
public static Class getJavaPrimitive(Class<?> cls) {
if (cls.isPrimitive()) return cls;
if (cls == Double.class) return double.class;
else if (cls == Integer.class) return int.class;
else if (cls == Boolean.class) return Boolean.class;
else if (cls == Byte.class) return byte.class;
else if (cls == Short.class) return short.class;
else if (cls == Long.class) return long.class;
else if (cls == Float.class) return float.class;
return null;
}
/**
* Try to convert an object to a destination type, especially for primitive types (int, double etc.
* but also Integer, Double etc.).

View File

@ -1,6 +1,5 @@
package eva2.gui;
import java.awt.Color;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyEditorManager;
@ -108,6 +107,11 @@ public class PropertyEditorProvider {
if (editor == null) editor = PropertyEditorManager.findEditor(type);
if (TRACE) System.out.println((editor == null ) ? "No editor from PEM by type" : ("Found " + editor.getClass()));
if (editor == null && (BeanInspector.isJavaPrimitive(value.getClass()))) {
Class<?> prim = BeanInspector.getJavaPrimitive(value.getClass());
if (prim!=null) editor = PropertyEditorManager.findEditor(prim);
}
if ((editor == null) && useDefaultGOE ) {
if (type.isArray()) editor = new GenericArrayEditor();
else if (type.isEnum()) editor = new EnumEditor();

View File

@ -203,7 +203,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
int methsFound = 0; // dont loop too long, so count until all found
// unhide all properties
// TODO this may be superfluous?
boolean[] hideStateBackup = GenericObjectEditor.setHideAllProperties(m_Target.getClass(), false);
// boolean[] hideStateBackup = GenericObjectEditor.setHideAllProperties(m_Target.getClass(), false);
// System.out.println("hide stats were: " + BeanInspector.toString(hideStateBackup));
for (int i = 0; i < m_Methods.length; i++) {
String name = m_Methods[i].getDisplayName();
@ -229,7 +229,7 @@ public class PropertySheetPanel extends JPanel implements PropertyChangeListener
if (methsFound == 3) break; // small speed-up
} // end for (int i = 0; i < m_Methods.length; i++) {
// restore hide states of all properties
GenericObjectEditor.setHideProperties(m_Target.getClass(), hideStateBackup);
// GenericObjectEditor.setHideProperties(m_Target.getClass(), hideStateBackup);
// Now lets search for the individual properties, their
// values, views and editors...

View File

@ -17,6 +17,7 @@ import eva2.server.go.PopulationInterface;
import eva2.server.go.individuals.AbstractEAIndividual;
import eva2.server.go.individuals.AbstractEAIndividualComparator;
import eva2.server.go.individuals.InterfaceDataTypeDouble;
import eva2.server.go.individuals.InterfaceGAIndividual;
import eva2.server.go.operators.distancemetric.EuclideanMetric;
import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric;
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
@ -55,6 +56,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
protected Population m_Archive = null;
PopulationInitMethod initMethod = PopulationInitMethod.individualDefault;
private double[] seedPos = new double[10];
private Pair<Integer,Integer> seedCardinality=new Pair<Integer,Integer>(5,1);
private double aroundDist=0.1;
transient private ArrayList<InterfacePopulationChangedEventListener> listeners = null;
// the evaluation interval at which listeners are notified
@ -173,6 +176,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
this.notifyEvalInterval = population.notifyEvalInterval;
this.initMethod = population.initMethod;
this.aroundDist = population.aroundDist;
this.seedCardinality = population.seedCardinality.clone();
if (population.seedPos!=null) this.seedPos = population.seedPos.clone();
// this.m_Listener = population.m_Listener;
if (population.listeners != null) this.listeners = (ArrayList<InterfacePopulationChangedEventListener>)population.listeners.clone();
@ -287,6 +291,9 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
PostProcess.createPopInSubRange(this, aroundDist, this.getTargetSize(), template);
} else System.err.println("Warning, skipping seed initialization: too small individual seed!");
break;
case binCardinality:
createBinCardinality(this, true, seedCardinality.head(), seedCardinality.tail());
break;
}
firePropertyChangedEvent(Population.populationInitialized);
}
@ -356,9 +363,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return;
}
AbstractEAIndividual template = pop.getEAIndividual(0);
if (fillPop && (pop.size()<pop.getTargetSize())) {
for (int i=pop.size(); i<pop.getTargetSize(); i++) pop.add((AbstractEAIndividual)template.clone());
}
if (fillPop) pop.fill(template);
if (template instanceof InterfaceDataTypeDouble) {
double[][] range = ((InterfaceDataTypeDouble)template).getDoubleRange();
// Population pop = new Population(popSize);
@ -372,6 +377,53 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
}
}
/**
* Initialize a population of GA individuals with a certain cardinality and possibly variation.
* At least one template individual must be contained in the population. All individuals must have
* binary genotypes. The bitsets are then initialized with the given cardinality (random no. bits set)
* and possibly gaussian variation defined by std.dev. which is truncated at zero and the genotype length.
*
* @param pop the population instance
* @param fillPop if true, fill the population up to the target size
* @param cardinality an integer giving the number of (random) bits to set
* @param stdDev standard deviation of the cardinality variation (can be zero to fix the cardinality)
* @return
*/
public static void createBinCardinality(Population pop, boolean fillPop, int cardinality, int stdDev) {
if (pop.size()<=0) {
System.err.println("createBinCardinality needs at least one template individual in the population");
return;
}
AbstractEAIndividual template = pop.getEAIndividual(0);
if (fillPop) pop.fill(template);
if (template instanceof InterfaceGAIndividual) {
// InterfaceGAIndividual gaIndy = (InterfaceGAIndividual)template;
for (int i=0; i<pop.size(); i++) {
InterfaceGAIndividual gaIndy = (InterfaceGAIndividual)pop.getEAIndividual(i);
int curCard = cardinality;
if (stdDev>0) curCard += (int)Math.round(RNG.gaussianDouble((double)stdDev));
curCard=Math.max(0, Math.min(curCard, gaIndy.getGenotypeLength()));
// System.out.println("Current cardinality: " + curCard);
gaIndy.SetBGenotype(RNG.randomBitSet(curCard, gaIndy.getGenotypeLength()));
// System.out.println(pop.getEAIndividual(i));
}
} else {
System.err.println("Error: InterfaceGAIndividual required for binary cardinality initialization!");
}
}
/**
* Fill the population up to the target size with clones of a template individual.
*
* @param template a template individual used to fill the population
*/
public void fill(AbstractEAIndividual template) {
if (this.size()<this.getTargetSize()) {
for (int i=this.size(); i<this.getTargetSize(); i++) {
this.add((AbstractEAIndividual)template.clone());
}
}
}
/**
* Activate or deactivate the history tracking, which stores the best individual in every
* generation in the incrGeneration() method.
@ -2139,6 +2191,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
this.initMethod = initMethod;
GenericObjectEditor.setShowProperty(this.getClass(), "initAround", initMethod==PopulationInitMethod.aroundSeed);
GenericObjectEditor.setShowProperty(this.getClass(), "initPos", initMethod==PopulationInitMethod.aroundSeed);
GenericObjectEditor.setShowProperty(this.getClass(), "seedCardinality", initMethod==PopulationInitMethod.binCardinality);
}
public String initMethodTipText() {
@ -2328,6 +2381,16 @@ public class Population extends ArrayList implements PopulationInterface, Clonea
return (bestIndy==null) ? null : (AbstractEAIndividual)bestIndy.clone();
}
public Pair<Integer, Integer> getSeedCardinality() {
return seedCardinality;
}
public void setSeedCardinality(Pair<Integer, Integer> seedCardinality) {
this.seedCardinality = seedCardinality;
}
public String seedCardinalityTipText() {
return "The initial cardinality for binary genotype individuals, given as pair of mean and std.dev.";
}
// /**
// * Mark the population at the current state as evaluated. Changes to the modCount or hashes of individuals
// * will invalidate the mark.

View File

@ -1,5 +1,5 @@
package eva2.server.go.populations;
public enum PopulationInitMethod {
individualDefault, randomLatinHypercube, aroundSeed;
individualDefault, randomLatinHypercube, aroundSeed, binCardinality;
}

View File

@ -26,6 +26,8 @@ public class Pair<S, T> implements Serializable {
this.tail = tail;
}
public Pair() {
}
/**
*
* @return
@ -69,6 +71,18 @@ public class Pair<S, T> implements Serializable {
return head;
}
/**
*
* @return
*/
public S getHead() {
return head;
}
public String headTipText() {
return "First pair entry";
}
/**
*
* @return
@ -77,6 +91,14 @@ public class Pair<S, T> implements Serializable {
return tail;
}
public T getTail() {
return tail;
}
public String tailTipText() {
return "Last pair entry";
}
/*
* (non-Javadoc)
*
@ -87,6 +109,10 @@ public class Pair<S, T> implements Serializable {
return "(" + head.toString() + "," + tail.toString() + ")";
}
public String getName() {
return this.toString();
}
/**
*
* @param head

View File

@ -1,6 +1,7 @@
package eva2.tools.math;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Random;
@ -98,32 +99,6 @@ public class RNG {
return result;
}
/**
* This method returns a random permutation of n int values
*
* @param length
* The number of int values
* @return The permutation [0-length-1]
*/
public static int[] randomPermutation(int length) {
boolean[] validList = new boolean[length];
int[] result = new int[length];
int index;
for (int i = 0; i < validList.length; i++)
validList[i] = true;
for (int i = 0; i < result.length; i++) {
index = randomInt(0, length - 1);
while (!validList[index]) {
index++;
if (index == length)
index = 0;
}
validList[index] = false;
result[i] = index;
}
return result;
}
/**
* This method returns a random permutation of n int values
*
@ -310,6 +285,29 @@ public class RNG {
return randomInt();
}
/**
* Create a random bitset with given cardinality and lengths,
*/
public static BitSet randomBitSet(int cardinality, int length) {
BitSet bs = new BitSet(length);
int[] perm = randomPerm(length);
for (int i=0; i<cardinality; i++) {
bs.set(perm[i]);
}
return bs;
}
/**
* Create a random bitset with a given probability of 1 per bit.
*/
public static BitSet randomBitSet(double pSet, int length) {
BitSet bs = new BitSet(length);
for (int i=0; i<length; i++) {
if (flipCoin(pSet)) bs.set(i);
}
return bs;
}
/**
* Returns true with probability p.
*