Adding ScatterSearch and modifications of BSS/BOA (seitz rev. 930)
This commit is contained in:
parent
13782ad1e8
commit
ddbebe2c48
@ -9,6 +9,8 @@ import eva2.tools.BasicResourceLoader;
|
||||
* Main product and version information strings.
|
||||
*
|
||||
* ---- Changelog
|
||||
* 2.047: Added ScatterSearch (real-valued), BinaryScatterSearch, and the Bayesian Optimization Algorithm (thanks
|
||||
* to Alexander Seitz) to the base package.
|
||||
* 2.046: Adaptions to the MatlabInterface: explicit data types are used now, added integer problem support.
|
||||
* Additional Integer operators: segment-wise mutation and crossover. Added an abstraction over individual
|
||||
* initialization methods. Added the ERPStarter class which is an example for running a csv-configured
|
||||
|
@ -126,9 +126,11 @@ public class BOA implements InterfaceOptimizer, java.io.Serializable {
|
||||
*/
|
||||
private void evaluate(AbstractEAIndividual indy){
|
||||
// evaluate the given individual if it is not null
|
||||
if(indy != null){
|
||||
this.problem.evaluate(indy);
|
||||
if(indy == null){
|
||||
System.err.println("tried to evaluate null");
|
||||
return;
|
||||
}
|
||||
this.problem.evaluate(indy);
|
||||
// increment the number of evaluations
|
||||
this.population.incrFunctionCalls();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ import eva2.tools.math.RNG;
|
||||
* Computers and Operations research, vol. 37, no. 11, pp. 1977-1986 (2010)
|
||||
*/
|
||||
public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializable, InterfacePopulationChangedEventListener {
|
||||
private static boolean TRACE = false;
|
||||
private static boolean TRACE = true;
|
||||
transient private InterfacePopulationChangedEventListener m_Listener = null;
|
||||
private String m_Identifier = "BinaryScatterSearch";
|
||||
|
||||
@ -81,10 +81,10 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
this.g1 = b.g1;
|
||||
this.g2 = b.g2;
|
||||
this.firstTime = b.firstTime;
|
||||
this.template = b.template;
|
||||
this.problem = b.problem;
|
||||
this.pool = b.pool;
|
||||
this.refSet = b.refSet;
|
||||
this.template = (AbstractEAIndividual) b.template.clone();
|
||||
this.problem = (AbstractOptimizationProblem) b.problem.clone();
|
||||
this.pool = (Population) b.pool.clone();
|
||||
this.refSet = (Population) b.refSet.clone();
|
||||
this.cross = b.cross;
|
||||
}
|
||||
|
||||
@ -165,9 +165,11 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
*/
|
||||
private void evaluate(AbstractEAIndividual indy){
|
||||
// evaluate the given individual if it is not null
|
||||
if(indy != null){
|
||||
this.problem.evaluate(indy);
|
||||
if(indy == null){
|
||||
System.err.println("tried to evaluate null");
|
||||
return;
|
||||
}
|
||||
this.problem.evaluate(indy);
|
||||
// increment the number of evaluations
|
||||
this.refSet.incrFunctionCalls();
|
||||
}
|
||||
@ -218,22 +220,46 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
* @return a diversified Population with all the Individuals in the initial Population
|
||||
*/
|
||||
private Population diversify(Population pop){
|
||||
pop = generateG1(pop);
|
||||
pop = generateG2(pop);
|
||||
pop = generateG3(pop);
|
||||
int numToInit = this.poolSize - pop.size();
|
||||
if (numToInit>0) {
|
||||
pop.addAll(generateG1((int)(numToInit * this.g1)));
|
||||
if (TRACE) System.out.println("s1: " + pop.size());
|
||||
generateG2(pop, (int)(numToInit * this.g2));
|
||||
if (TRACE) System.out.println("s2: " + pop.size());
|
||||
generateG3(pop, poolSize-pop.size());
|
||||
if (TRACE) System.out.println("s3: " + pop.size());
|
||||
}
|
||||
return pop;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a new Population with diverse Individuals starting with 000...000, then 010101...01, 101010...10, 001001001...001, 110110110...110 and so on
|
||||
* Generate a new Population with diverse Individuals starting with 000...000,
|
||||
* then 010101...01, 101010...10, 001001001...001, 110110110...110 and so on
|
||||
* The returned population is evaluated.
|
||||
* @param pop the initial Population
|
||||
* @return the new Population
|
||||
*/
|
||||
private Population generateG1(Population pop){
|
||||
private Population generateG1(int numToInit){
|
||||
boolean method1 = true;
|
||||
Population pop = generateG1Pop(numToInit, this.template);
|
||||
for (int i=0; i<pop.size(); i++) {
|
||||
evaluate(pop.getEAIndividual(i));
|
||||
}
|
||||
return pop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new Population with diverse Individuals starting with 000...000, then 010101...01,
|
||||
* 101010...10, 001001001...001, 110110110...110 and so on
|
||||
* @param pop the initial Population
|
||||
* @return the new Population
|
||||
*/
|
||||
public static Population generateG1Pop(int targetSize, AbstractEAIndividual template){
|
||||
boolean method1 = true;
|
||||
int i=1;
|
||||
while(pop.size() < ((double) this.poolSize) * this.g1){
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual) this.template.clone();
|
||||
Population pop = new Population(targetSize);
|
||||
while(pop.size() < targetSize) {
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual) template.clone();
|
||||
BitSet data = getBinaryData(indy);
|
||||
if(method1){
|
||||
method1 = !method1;
|
||||
@ -258,18 +284,18 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
i++;
|
||||
}
|
||||
pop.add(indy);
|
||||
evaluate((AbstractEAIndividual) indy);
|
||||
}
|
||||
return pop;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate new Individuals that have the individuals of the given Population as a base
|
||||
* @param pop the population
|
||||
* @return the new Population
|
||||
*/
|
||||
private Population generateG2(Population pop){
|
||||
while(pop.size() < ((double) this.poolSize) * (this.g1 + this.g2)){
|
||||
private Population generateG2(Population pop, int numToInit){
|
||||
int origSize = pop.size();
|
||||
while(pop.size() < origSize+numToInit){
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
|
||||
InterfaceDataTypeBinary dblIndy = (InterfaceDataTypeBinary) indy;
|
||||
BitSet data = dblIndy.getBinaryData();
|
||||
@ -293,8 +319,9 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
* @param pop the population
|
||||
* @return the new Population
|
||||
*/
|
||||
private Population generateG3(Population pop){
|
||||
while(pop.size() <= this.poolSize){
|
||||
private Population generateG3(Population pop, int numToInit){
|
||||
int origSize = pop.size();
|
||||
while(pop.size() < origSize+numToInit){
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
|
||||
InterfaceDataTypeBinary dblIndy = (InterfaceDataTypeBinary)indy;
|
||||
BitSet data = dblIndy.getBinaryData();
|
||||
@ -607,7 +634,6 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
}
|
||||
this.cross.update(indy1, problem, refSet, indy1.getFitness(0));
|
||||
result = this.cross.mate(indy1, pop)[0];
|
||||
evaluate(null);
|
||||
//result = indy1.mateWith(s)[0];
|
||||
}else if(pop.size()>0){
|
||||
result = pop.getBestEAIndividual();
|
||||
@ -656,7 +682,7 @@ public class BinaryScatterSearch implements InterfaceOptimizer, java.io.Serializ
|
||||
this.refSet.incrFunctionCallsBy(this.pool.size());
|
||||
// increase the number of evaluations by the number of evaluations that are performed in the crossover-step
|
||||
for(int i=0; i<this.cross.getEvaluations(); i++){
|
||||
evaluate(null);
|
||||
this.refSet.incrFunctionCalls();
|
||||
}
|
||||
// reset the extra evaluations
|
||||
this.cross.resetEvaluations();
|
||||
|
931
src/eva2/server/go/strategies/ScatterSearch.java
Normal file
931
src/eva2/server/go/strategies/ScatterSearch.java
Normal file
@ -0,0 +1,931 @@
|
||||
package eva2.server.go.strategies;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import eva2.OptimizerFactory;
|
||||
import eva2.OptimizerRunnable;
|
||||
import eva2.gui.BeanInspector;
|
||||
import eva2.gui.GenericObjectEditor;
|
||||
import eva2.server.go.InterfacePopulationChangedEventListener;
|
||||
import eva2.server.go.InterfaceTerminator;
|
||||
import eva2.server.go.individuals.AbstractEAIndividual;
|
||||
import eva2.server.go.individuals.InterfaceDataTypeDouble;
|
||||
import eva2.server.go.operators.distancemetric.PhenotypeMetric;
|
||||
import eva2.server.go.operators.postprocess.PostProcess;
|
||||
import eva2.server.go.operators.terminators.EvaluationTerminator;
|
||||
import eva2.server.go.populations.InterfaceSolutionSet;
|
||||
import eva2.server.go.populations.Population;
|
||||
import eva2.server.go.populations.SolutionSet;
|
||||
import eva2.server.go.problems.AbstractOptimizationProblem;
|
||||
import eva2.server.go.problems.F1Problem;
|
||||
import eva2.server.go.problems.InterfaceOptimizationProblem;
|
||||
import eva2.server.modules.GOParameters;
|
||||
import eva2.tools.Pair;
|
||||
import eva2.tools.SelectedTag;
|
||||
import eva2.tools.math.Mathematics;
|
||||
import eva2.tools.math.RNG;
|
||||
|
||||
/**
|
||||
* A ScatterSearch implementation taken mainly from [1]. Unfortunately, some parameters as well as
|
||||
* the local search method are not well defined in [1], so this implementation allows HC and Nelder-Mead
|
||||
* as local search. If local search is activated, an additional filter is defined, meaning that only those
|
||||
* individuals with a high quality fitness are further improved by local search.
|
||||
* The threshold fitness is either defined relatively to the best/worst fitness values in the reference set
|
||||
* or as an absolute value (in both cases only the first fitness criterion is regarded).
|
||||
*
|
||||
* @author mkron
|
||||
*
|
||||
* [1] M.Rodiguez-Fernandez, J.Egea, J.Banga: Novel metaheuristic for parameter estimation in nonlinear dynamic biological systems.
|
||||
* BMC Bioinformatics 2006, 7:483. BioMed Central 2006.
|
||||
*/
|
||||
public class ScatterSearch implements InterfaceOptimizer, java.io.Serializable, InterfacePopulationChangedEventListener {
|
||||
transient private InterfacePopulationChangedEventListener m_Listener = null;
|
||||
private String m_Identifier = "ScatterSearch";
|
||||
private AbstractOptimizationProblem problem = new F1Problem();
|
||||
private Population oldRefSet, refSet = new Population(10);
|
||||
private transient Population combinations = null;
|
||||
private AbstractEAIndividual template = null;
|
||||
private double[][] range = null;
|
||||
private int refSetSize = 10; // default: 10
|
||||
private int poolSize = 100; // default: 10*refSetSize;
|
||||
// splitting each dimension into intervals to do diverse initialization
|
||||
private int intervals = 4;
|
||||
private int localSearchSteps = 100;
|
||||
private double localSearchFitnessFilter = 1.5;
|
||||
private int probDim = -1;
|
||||
private boolean firstTime = true;
|
||||
private int lastImprovementCount = 0;
|
||||
private SelectedTag localSearchMethod = new SelectedTag(1, "Hill-Climber", "Nelder-Mead");
|
||||
// simulate an EvA generational cycle
|
||||
private int generationCycle = 50;
|
||||
private int fitCrit = -1;
|
||||
|
||||
protected boolean checkRange = true;
|
||||
|
||||
// private int lastLocalSearch = -1;
|
||||
// // nr of generations between local searches
|
||||
// protected int localSearchInterval = 10;
|
||||
// below this threshold a local search will be performed
|
||||
// protected double fitThreshLocalSearch = 1000.;
|
||||
protected boolean doLocalSearch = false;
|
||||
private boolean relativeFitCriterion = false;
|
||||
private double nelderMeadInitPerturbation = 0.01;
|
||||
private double improvementEpsilon = 0.1; // minimal relative fitness improvement for a candidate to be taken over into the refset
|
||||
private double minDiversityEpsilon = 0.0001; // minimal phenotypic distance for a candidate to be taken over into the refset
|
||||
|
||||
private static boolean TRACE = false;
|
||||
|
||||
public ScatterSearch() {
|
||||
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
|
||||
hideHideable();
|
||||
}
|
||||
|
||||
public ScatterSearch(ScatterSearch o) {
|
||||
this.refSet = (Population)o.refSet.clone();
|
||||
this.problem = (AbstractOptimizationProblem)o.problem.clone();
|
||||
this.template = (AbstractEAIndividual)o.template.clone();
|
||||
this.range = ((InterfaceDataTypeDouble)template).getDoubleRange();
|
||||
this.refSetSize = o.refSetSize;
|
||||
this.poolSize = o.poolSize;
|
||||
this.intervals = o.intervals;
|
||||
this.localSearchSteps = o.localSearchSteps;
|
||||
this.localSearchFitnessFilter = o.localSearchFitnessFilter;
|
||||
this.probDim = o.probDim;
|
||||
this.firstTime = o.firstTime;
|
||||
this.lastImprovementCount = o.lastImprovementCount;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return new ScatterSearch(this);
|
||||
}
|
||||
|
||||
public void hideHideable() {
|
||||
setLSShowProps();
|
||||
GenericObjectEditor.setHideProperty(this.getClass(), "population", true);
|
||||
}
|
||||
|
||||
public void SetProblem(InterfaceOptimizationProblem problem) {
|
||||
this.problem = (AbstractOptimizationProblem)problem;
|
||||
}
|
||||
|
||||
public InterfaceSolutionSet getAllSolutions() {
|
||||
return new SolutionSet(refSet);
|
||||
}
|
||||
|
||||
public Population getPopulation() {
|
||||
return refSet;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
defaultInit();
|
||||
initRefSet(diversify());
|
||||
}
|
||||
|
||||
public void initByPopulation(Population pop, boolean reset) {
|
||||
defaultInit();
|
||||
|
||||
initRefSet(diversify(pop));
|
||||
}
|
||||
|
||||
/**
|
||||
* Eval an initial population and extract the first refset.
|
||||
* @param pop
|
||||
*/
|
||||
private void initRefSet(Population pop) {
|
||||
problem.evaluate(pop);
|
||||
if (TRACE) {
|
||||
System.out.println("building ref set from pop with avg dist " + pop.getPopulationMeasures()[0]);
|
||||
}
|
||||
refSet = getRefSetFitBased(new Population(refSetSize), pop);
|
||||
refSet.incrFunctionCallsBy(pop.size());
|
||||
if (TRACE) {
|
||||
System.out.println("ref set size " + refSet.size() + " avg dist " + refSet.getPopulationMeasures()[0]);
|
||||
}
|
||||
refSet.addPopulationChangedEventListener(this);
|
||||
refSet.setNotifyEvalInterval(generationCycle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do default initialization.
|
||||
*/
|
||||
private void defaultInit() {
|
||||
firstTime=true;
|
||||
refSet = null;
|
||||
combinations = null;
|
||||
template = problem.getIndividualTemplate();
|
||||
if (!(template instanceof InterfaceDataTypeDouble)) System.err.println("Requiring double data!");
|
||||
else {
|
||||
Object dim = BeanInspector.callIfAvailable(problem, "getProblemDimension", null);
|
||||
if (dim==null) System.err.println("Couldnt get problem dimension!");
|
||||
probDim = (Integer)dim;
|
||||
range = ((InterfaceDataTypeDouble)template).getDoubleRange();
|
||||
if (TRACE) System.out.println("Range is " + BeanInspector.toString(range));
|
||||
}
|
||||
}
|
||||
|
||||
/** Something has changed
|
||||
*/
|
||||
protected void firePropertyChangedEvent (String name) {
|
||||
if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name);
|
||||
}
|
||||
|
||||
// public double eval(double[] x) {
|
||||
// AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
|
||||
// ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(x);
|
||||
// problem.evaluate(indy);
|
||||
// return indy.getFitness(0);
|
||||
// }
|
||||
|
||||
public void registerPopulationStateChanged(Object source, String name) {
|
||||
// The events of the interim hill climbing population will be caught here
|
||||
if (name.compareTo(Population.funCallIntervalReached) == 0) {
|
||||
// if ((((Population)source).size() % 50) > 0) {
|
||||
// System.out.println("bla");
|
||||
// }
|
||||
// set funcalls to real value
|
||||
refSet.SetFunctionCalls(((Population)source).getFunctionCalls());
|
||||
|
||||
// System.out.println("FunCallIntervalReached at " + (((Population)source).getFunctionCalls()));
|
||||
|
||||
this.firePropertyChangedEvent(Population.nextGenerationPerformed);
|
||||
}
|
||||
// do not react to NextGenerationPerformed
|
||||
//else System.err.println("ERROR, event was " + name);
|
||||
}
|
||||
|
||||
public void optimize() {
|
||||
// Diversification
|
||||
// Refset Formation
|
||||
// L: Combination of refset elements
|
||||
// if (localSolverCall) then
|
||||
// if (pass filters) then compute local solvers
|
||||
// refset update
|
||||
// if (uncombined elements) then goto L
|
||||
// if (!stop criterion) then
|
||||
// refset regeneration
|
||||
// goto L
|
||||
if (!firstTime) {
|
||||
if (lastImprovementCount == 0) refSet = regenerateRefSet();
|
||||
}
|
||||
firstTime = false;
|
||||
|
||||
problem.evaluatePopulationStart(refSet);
|
||||
int funCallsStart = refSet.getFunctionCalls();
|
||||
do {
|
||||
if (combinations == null || combinations.size() == 0) {
|
||||
if (TRACE) {
|
||||
System.out.println("Improvements: " + lastImprovementCount);
|
||||
System.out.println("---------- best: " + refSet.getBestEAIndividual().getFitness(0));
|
||||
}
|
||||
combinations = generateCombinations(refSet);
|
||||
oldRefSet = (Population) refSet.clone();
|
||||
lastImprovementCount = 0;
|
||||
}
|
||||
if (TRACE) System.out.println("No combinations: " + combinations.size());
|
||||
if (combinations.size()>0) {
|
||||
updateRefSet(refSet, combinations, oldRefSet);
|
||||
}
|
||||
} while (refSet.getFunctionCalls()-funCallsStart < generationCycle);
|
||||
problem.evaluatePopulationEnd(refSet);
|
||||
|
||||
if (TRACE) {
|
||||
System.out.println("Improvements: " + lastImprovementCount);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isDoLocalSolver(AbstractEAIndividual cand, Population refSet) {
|
||||
// if (lastLocalSearch + localSearchInterval < refSet.getGeneration()) {
|
||||
if (doLocalSearch) {
|
||||
// filter: only check those within 50% of the worst indy relative to the best.
|
||||
if (relativeFitCriterion) {
|
||||
double fitRange = refSet.getWorstFitness()[0] - refSet.getBestFitness()[0];
|
||||
return (cand.getFitness(0) < (refSet.getBestFitness()[0]+(fitRange*localSearchFitnessFilter)));
|
||||
} else {
|
||||
// absolute fitness criterion
|
||||
return (cand.getFitness(0) < localSearchFitnessFilter);
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
|
||||
private Population regenerateRefSet() {
|
||||
Population diversifiedPop = diversify();
|
||||
int keep = refSetSize/2;
|
||||
Population newRefSet = refSet.cloneWithoutInds();
|
||||
if (TRACE) System.out.println("regen after " + refSet.getFunctionCalls() + ", best is " + refSet.getBestEAIndividual().getFitness(0));
|
||||
|
||||
newRefSet.addAll(refSet.getBestNIndividuals(keep, fitCrit));
|
||||
|
||||
if (TRACE) System.out.println("keeping " + keep + " indies from former ref set, best is " + newRefSet.getBestEAIndividual().getFitness(0));
|
||||
|
||||
int h=newRefSet.size();
|
||||
ArrayList<double[]> distVects = new ArrayList<double[]>();
|
||||
for (int i=1; i<h; i++) {
|
||||
distVects.add(getDiffVect(newRefSet.getEAIndividual(0), newRefSet.getEAIndividual(i)));
|
||||
}
|
||||
|
||||
double maxSP = -1;
|
||||
int sel = -1;
|
||||
while (h<refSetSize) {
|
||||
for (int i=0; i<diversifiedPop.size(); i++) {
|
||||
// the difference of cand and best is multiplied by each earlier difference from refSet indies
|
||||
double[] vP = calcVectP(diversifiedPop.getEAIndividual(i), newRefSet.getEAIndividual(0), distVects);
|
||||
double maxTmp = getMaxInVect(vP);
|
||||
if ((i==0) || (maxTmp < maxSP)) {
|
||||
maxSP = maxTmp;
|
||||
sel = i;
|
||||
}
|
||||
// selected the one with smallest maxSP!
|
||||
}
|
||||
AbstractEAIndividual winner = diversifiedPop.getEAIndividual(sel);
|
||||
// evaluate the new indy
|
||||
problem.evaluate(winner);
|
||||
// add it to the newRefSet, increase h
|
||||
newRefSet.add(winner);
|
||||
newRefSet.incrFunctionCalls();
|
||||
// newRefSet not sorted anymore?
|
||||
h++;
|
||||
// update distVects
|
||||
distVects.add(getDiffVect(newRefSet.getEAIndividual(0), winner));
|
||||
// remove from pop.
|
||||
diversifiedPop.remove(sel);
|
||||
// redo the loop
|
||||
}
|
||||
return newRefSet;
|
||||
}
|
||||
|
||||
private double getMaxInVect(double[] vals) {
|
||||
double dmax = vals[0];
|
||||
for (int j=1; j<vals.length; j++) {
|
||||
if (vals[j] > dmax) {
|
||||
dmax = vals[j];
|
||||
}
|
||||
}
|
||||
return dmax;
|
||||
}
|
||||
|
||||
private double[] calcVectP(AbstractEAIndividual candidate, AbstractEAIndividual best, ArrayList<double[]> distVects) {
|
||||
// p = (best - candidate)*transposed(M)
|
||||
double[] diff = getDiffVect(best, candidate);
|
||||
return multScalarTransposed(diff, distVects);
|
||||
}
|
||||
|
||||
private double[] multScalarTransposed(double[] diff, ArrayList<double[]> distVects) {
|
||||
// d[0]*m[0][0], d[1]*m[0][1] etc.
|
||||
double[] res = new double[distVects.size()];
|
||||
for (int i=0; i<distVects.size(); i++) res[i] = Mathematics.vvMult(diff, distVects.get(i));
|
||||
return res;
|
||||
}
|
||||
|
||||
private double[] getDiffVect(AbstractEAIndividual indy1, AbstractEAIndividual indy2) {
|
||||
double[] v1 = ((InterfaceDataTypeDouble)indy1).getDoubleData();
|
||||
double[] v2 = ((InterfaceDataTypeDouble)indy2).getDoubleData();
|
||||
return Mathematics.vvSub(v1, v2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maybe replace the single worst indy in the refset by the best candidate, which may
|
||||
* be locally optimized in a local search step.
|
||||
* The best candidate is removed from the candidate set in any case. The candidate set
|
||||
* may be cleared if all following individuals would never be taken over to the refset.
|
||||
*
|
||||
* @param refSet
|
||||
* @param candidates
|
||||
* @param oldRefSet only to be used as for phenotypic diversity measure
|
||||
*/
|
||||
private void updateRefSet(Population refSet, Population candidates, Population oldRefSet) {
|
||||
int bestIndex = candidates.getIndexOfBestIndividualPrefFeasible();
|
||||
AbstractEAIndividual bestCand = candidates.getEAIndividual(bestIndex);
|
||||
AbstractEAIndividual worstRef = refSet.getWorstEAIndividual();
|
||||
|
||||
if (TRACE) {
|
||||
System.out.println("best cand: " + bestCand.getFitness(0));
|
||||
}
|
||||
|
||||
if (isDoLocalSolver(bestCand, refSet)) {
|
||||
Pair<AbstractEAIndividual, Integer> lsRet = localSolver(bestCand, localSearchSteps);
|
||||
if ((Math.abs(lsRet.tail() - localSearchSteps)/localSearchSteps) > 0.05) System.err.println("Warning, more than 5% difference in local search step");
|
||||
bestCand = lsRet.head();
|
||||
refSet.incrFunctionCallsBy(lsRet.tail());
|
||||
if (TRACE) {
|
||||
System.out.println("best cand after: " + bestCand.getFitness(0));
|
||||
}
|
||||
}
|
||||
|
||||
if (bestCand.isDominatingEqual(worstRef)) {
|
||||
if (TRACE) System.out.println("cand is dominating worst ref!");
|
||||
if (diversityCriterionFulfilled(bestCand, refSet, oldRefSet)) {
|
||||
// System.out.println("diversity criterion is fulfilled! replacing fit " + worstRef.getFitness(0));
|
||||
int replIndex = refSet.indexOf(worstRef);
|
||||
refSet.set(replIndex, bestCand);
|
||||
lastImprovementCount++;
|
||||
} else if (bestCand.isDominating(refSet.getBestEAIndividual())) {
|
||||
// exception: always accept best solution found so far
|
||||
int closestIndex = getClosestIndy(bestCand, refSet);
|
||||
// if (TRACE) System.out.println("replacing due to best fit");
|
||||
refSet.set(closestIndex, bestCand);
|
||||
lastImprovementCount++;
|
||||
}
|
||||
// System.out.println("Improvements: " + lastImprovementCount);
|
||||
candidates.remove(bestIndex);
|
||||
} else {
|
||||
if (TRACE) System.out.println("cand is too bad!");
|
||||
// if the best candidate is worse and no local search is performed, all following will be worse - at least in the uni-criterial case
|
||||
// so we can just clear the rest of the candidates
|
||||
if (!doLocalSearch && (bestCand.getFitness().length == 1)) candidates.clear();
|
||||
else candidates.remove(bestIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<AbstractEAIndividual, Integer> localSolver(AbstractEAIndividual cand, int hcSteps) {
|
||||
if (localSearchMethod.getSelectedTagID()==0) return localSolverHC(cand, hcSteps);
|
||||
else return PostProcess.localSolverNMS(cand, hcSteps, nelderMeadInitPerturbation, problem);
|
||||
}
|
||||
|
||||
private Pair<AbstractEAIndividual, Integer> localSolverHC(AbstractEAIndividual cand, int hcSteps) {
|
||||
// use HC for a start...
|
||||
// double[] fitBefore = cand.getFitness();
|
||||
Population hcPop = new Population(1);
|
||||
hcPop.add(cand);
|
||||
int stepsDone = PostProcess.processWithHC(hcPop, problem, hcSteps);
|
||||
// if (TRACE) {
|
||||
// System.out.println("local search result: from " + BeanInspector.toString(fitBefore) + " to " + BeanInspector.toString(hcPop.getEAIndividual(0).getFitness()));
|
||||
// }
|
||||
return new Pair<AbstractEAIndividual, Integer>(hcPop.getEAIndividual(0), stepsDone);
|
||||
}
|
||||
|
||||
private int getClosestIndy(AbstractEAIndividual indy, Population refSet) {
|
||||
double tmpDst, dist = PhenotypeMetric.dist(indy, refSet.getEAIndividual(0));
|
||||
int sel = 0;
|
||||
for (int i=1; i<refSet.size(); i++) {
|
||||
tmpDst = PhenotypeMetric.dist(indy, refSet.getEAIndividual(i));
|
||||
if (tmpDst < dist) {
|
||||
tmpDst = dist;
|
||||
sel = i;
|
||||
}
|
||||
}
|
||||
return sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for both a genotype and phenotype diversity criterion which both must
|
||||
* be fulfilled for a candidate to be accepted.
|
||||
*
|
||||
* @param cand
|
||||
* @param popCompGeno
|
||||
* @param popCompPheno
|
||||
* @return
|
||||
*/
|
||||
private boolean diversityCriterionFulfilled(AbstractEAIndividual cand, Population popCompGeno, Population popComPheno) {
|
||||
double minDist = PhenotypeMetric.dist(cand, popCompGeno.getEAIndividual(0));
|
||||
for (int i=1; i<popCompGeno.size(); i++) {
|
||||
minDist = Math.min(minDist, PhenotypeMetric.dist(cand, popCompGeno.getEAIndividual(i)));
|
||||
}
|
||||
|
||||
boolean minDistFulfilled = ((minDiversityEpsilon<=0) || (minDist > minDiversityEpsilon));
|
||||
|
||||
if (minDistFulfilled && (improvementEpsilon > 0)) {
|
||||
boolean minImprovementFulfilled = (cand.getFitness(0) < ((1.-improvementEpsilon) * popComPheno.getBestEAIndividual().getFitness(0)));
|
||||
return minImprovementFulfilled;
|
||||
} else return minDistFulfilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recombines the refset to new indies which are also evaluated.
|
||||
* @param refSet
|
||||
* @return
|
||||
*/
|
||||
private Population generateCombinations(Population refSet) {
|
||||
// 3 pair types: better-better, better-worse, worse-worse (half of the pop);
|
||||
Population combs = new Population();
|
||||
Population refSorted = refSet.getBestNIndividuals(refSet.size(), fitCrit);
|
||||
int half = refSet.size()/2;
|
||||
for (int i=0; i<half-1; i++) { // better-better
|
||||
AbstractEAIndividual indy1 = refSorted.getEAIndividual(i);
|
||||
for (int j=i+1; j<half; j++) {
|
||||
// if (TRACE) System.out.println("combi T bb, " + i+ "/" + j);
|
||||
AbstractEAIndividual indy2 = refSorted.getEAIndividual(j);
|
||||
combs.add(combineTypeOne(indy1, indy2));
|
||||
combs.add(combineTypeTwo(indy1, indy2));
|
||||
combs.add(combineTypeTwo(indy1, indy2));
|
||||
combs.add(combineTypeThree(indy1, indy2));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<half; i++) { // better-worse
|
||||
AbstractEAIndividual indy1 = refSorted.getEAIndividual(i);
|
||||
for (int j=half; j<refSet.size(); j++) {
|
||||
// if (TRACE) System.out.println("combi T bw, " + i+ "/" + j);
|
||||
AbstractEAIndividual indy2 = refSorted.getEAIndividual(j);
|
||||
combs.add(combineTypeOne(indy1, indy2));
|
||||
combs.add(combineTypeTwo(indy1, indy2));
|
||||
combs.add(combineTypeThree(indy1, indy2));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=half; i<refSet.size()-1; i++) { // worse-worse
|
||||
AbstractEAIndividual indy1 = refSorted.getEAIndividual(i);
|
||||
for (int j=i+1; j<refSet.size(); j++) {
|
||||
// if (TRACE) System.out.println("combi T ww, " + i+ "/" + j);
|
||||
AbstractEAIndividual indy2 = refSorted.getEAIndividual(j);
|
||||
combs.add(combineTypeTwo(indy1, indy2));
|
||||
if (RNG.flipCoin(0.5)) combs.add(combineTypeOne(indy1, indy2));
|
||||
else combs.add(combineTypeThree(indy1, indy2));
|
||||
}
|
||||
}
|
||||
|
||||
if (TRACE) System.out.println("created combinations " + combs.size() + " best is " + combs.getBestEAIndividual().getFitness(0) );
|
||||
return combs;
|
||||
}
|
||||
|
||||
private AbstractEAIndividual combineTypeOne(AbstractEAIndividual indy1, AbstractEAIndividual indy2) {
|
||||
return combine(indy1, indy2, true, false);
|
||||
}
|
||||
private AbstractEAIndividual combineTypeTwo(AbstractEAIndividual indy1, AbstractEAIndividual indy2) {
|
||||
return combine(indy1, indy2, true, true);
|
||||
}
|
||||
private AbstractEAIndividual combineTypeThree(AbstractEAIndividual indy1, AbstractEAIndividual indy2) {
|
||||
return combine(indy1, indy2, false, true);
|
||||
}
|
||||
|
||||
private AbstractEAIndividual combine(AbstractEAIndividual indy1, AbstractEAIndividual indy2, boolean bFirst, boolean bAdd) {
|
||||
AbstractEAIndividual resIndy = (AbstractEAIndividual)indy1.clone();
|
||||
double[] v1 = ((InterfaceDataTypeDouble)indy1).getDoubleData();
|
||||
double[] v2 = ((InterfaceDataTypeDouble)indy2).getDoubleData();
|
||||
|
||||
double[] dVect = RNG.randomDoubleArray(0, 1, probDim);
|
||||
for (int i=0; i<probDim; i++) dVect[i] *= (v2[i]-v1[i])/2.;
|
||||
double[] candidate = bFirst ? v1 : v2;
|
||||
double[] combi = bAdd ? Mathematics.vvAdd(candidate, dVect) : Mathematics.vvSub(candidate, dVect);
|
||||
if (checkRange) Mathematics.projectToRange(combi, range);
|
||||
((InterfaceDataTypeDouble)resIndy).SetDoubleGenotype(combi);
|
||||
problem.evaluate(resIndy);
|
||||
refSet.incrFunctionCalls();
|
||||
return resIndy;
|
||||
}
|
||||
|
||||
public void setPopulation(Population pop) {
|
||||
refSet = pop;
|
||||
}
|
||||
|
||||
private Population getRefSetFitBased(Population curRefSet, Population divPop) {
|
||||
int h=refSetSize/2;
|
||||
curRefSet.addAll(divPop.getBestNIndividuals(h, fitCrit));
|
||||
Population rest = divPop.getWorstNIndividuals(refSetSize-h, fitCrit);
|
||||
// contains worst indies
|
||||
double[][] distances = new double[rest.size()][refSetSize];
|
||||
|
||||
for (int i=0; i<distances.length; i++) { // compute euc. distances of all rest indies to all refset indies.
|
||||
for (int j=0; j<h; j++) distances[i][j]=PhenotypeMetric.dist(rest.getEAIndividual(i), curRefSet.getEAIndividual(j));
|
||||
}
|
||||
while (curRefSet.size()<refSetSize) {
|
||||
// "the vector having highest minimum distance will join the refset."
|
||||
int sel=selectHighestMinDistance(distances, h);
|
||||
// add the selected diverse indy
|
||||
curRefSet.add(rest.getEAIndividual(sel));
|
||||
// compute distances
|
||||
for (int i=0; i<distances.length; i++) distances[i][h]=PhenotypeMetric.dist(rest.getEAIndividual(i), curRefSet.getEAIndividual(h));
|
||||
// dont! remove it from the rest indi set
|
||||
//rest.remove(sel);
|
||||
// instead, set a min dist of -1 which will guarantee its not selected again
|
||||
distances[sel][0] = -1.;
|
||||
h++;
|
||||
}
|
||||
|
||||
curRefSet.synchSize();
|
||||
return curRefSet;
|
||||
}
|
||||
|
||||
private double getMinInCol(int col, int maxRow, double[][] vals) {
|
||||
double dmin = vals[col][0];
|
||||
if (dmin < 0) return dmin; // tweak for trick
|
||||
for (int j=1; j<maxRow; j++) {
|
||||
if (vals[col][j] < dmin) {
|
||||
dmin = vals[col][j];
|
||||
}
|
||||
}
|
||||
return dmin;
|
||||
}
|
||||
|
||||
private int selectHighestMinDistance(double[][] distances, int maxRow) {
|
||||
// first index: rest indies, sec index: refSet indies
|
||||
// select the first index with highest minimum.
|
||||
double highestMin = getMinInCol(0, maxRow, distances);
|
||||
int sel = 0;
|
||||
for (int i=1; i<distances.length; i++) {
|
||||
double dtmp = getMinInCol(i,maxRow,distances);
|
||||
if (dtmp > highestMin) {
|
||||
highestMin = dtmp;
|
||||
sel = i;
|
||||
}
|
||||
}
|
||||
return sel;
|
||||
}
|
||||
|
||||
private Population diversify() {
|
||||
return diversify(new Population());
|
||||
}
|
||||
|
||||
private Population diversify(Population pop) {
|
||||
int[][] freq = new int[probDim][intervals];
|
||||
if (pop.size() > 0) { // count the interval appearances of already given individuals.
|
||||
for (int k=0; k<pop.size(); k++) {
|
||||
double[] params = ((InterfaceDataTypeDouble)pop.getEAIndividual(k)).getDoubleData();
|
||||
for (int j=0; j<probDim; j++) {
|
||||
for (int iv = 0; iv<intervals; iv++) if (isInRangeInterval(params[j], j, iv)) freq[j][iv]++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// or start with diagonals
|
||||
for (int i=0; i<intervals; i++) {
|
||||
pop.add(createDiagIndies(i));
|
||||
for (int j=0; j<probDim; j++) freq[j][i]=1;
|
||||
}
|
||||
}
|
||||
|
||||
while (pop.size() < poolSize) {
|
||||
pop.add( createDiverseIndy(freq) );
|
||||
}
|
||||
pop.setTargetSize(poolSize);
|
||||
if (TRACE) {
|
||||
System.out.println("created diverse pop size " + pop.size());
|
||||
}
|
||||
return pop;
|
||||
}
|
||||
|
||||
private AbstractEAIndividual createDiverseIndy(int freq[][]) {
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
|
||||
InterfaceDataTypeDouble dblIndy = (InterfaceDataTypeDouble)indy;
|
||||
double[] genes = dblIndy.getDoubleData();
|
||||
|
||||
for (int i=0; i<probDim; i++) {
|
||||
int interv = selectInterv(i, freq);
|
||||
genes[i] = randInRangeInterval(i, interv);
|
||||
freq[i][interv]++;
|
||||
}
|
||||
|
||||
dblIndy.SetDoubleGenotype(genes);
|
||||
return indy;
|
||||
}
|
||||
|
||||
private double getFreqDepProb(int dim, int interv, int freq[][]) {
|
||||
double sum = 0;
|
||||
for (int k=0; k<intervals; k++) sum += (double)freq[dim][k];
|
||||
return freq[dim][interv]/sum;
|
||||
}
|
||||
|
||||
private int selectInterv(int dim, int freq[][]) {
|
||||
double[] probs = new double[intervals];
|
||||
for (int i=0; i<intervals; i++) probs[i] = getFreqDepProb(dim, i, freq);
|
||||
double rnd = RNG.randomDouble();
|
||||
int sel = 0;
|
||||
double sum = probs[0];
|
||||
while (sum < rnd) {
|
||||
sel++;
|
||||
sum+=probs[sel];
|
||||
}
|
||||
if (sum >= 1.0000001) System.err.println("Check this: sum>=1 in selectInterv");
|
||||
return sel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create probDim individuals where each dimension is initialized within
|
||||
* subinterval i for individual i.
|
||||
*
|
||||
* @param interval
|
||||
* @return
|
||||
*/
|
||||
private AbstractEAIndividual createDiagIndies(int interval) {
|
||||
AbstractEAIndividual indy = (AbstractEAIndividual)template.clone();
|
||||
InterfaceDataTypeDouble dblIndy = (InterfaceDataTypeDouble)indy;
|
||||
double[] genes = dblIndy.getDoubleData();
|
||||
for (int i=0; i<probDim; i++) genes[i] = randInRangeInterval(i, interval);
|
||||
dblIndy.SetDoubleGenotype(genes);
|
||||
return indy;
|
||||
}
|
||||
|
||||
private boolean isInRangeInterval(double d, int dim, int interval) {
|
||||
double dimStep = (range[dim][1]-range[dim][0])/intervals;
|
||||
double lowB = range[dim][0]+(dimStep*interval);
|
||||
double upB = lowB+dimStep;
|
||||
return isInRange(d, lowB, upB);
|
||||
}
|
||||
|
||||
private boolean isInRange(double d, double lowB, double upB) {
|
||||
return (lowB <= d) && (d < upB);
|
||||
}
|
||||
|
||||
private double randInRangeInterval(int dim, int interval) {
|
||||
double dimStep = (range[dim][1]-range[dim][0])/intervals;
|
||||
double lowB = range[dim][0]+(dimStep*interval);
|
||||
double upB = lowB+dimStep;
|
||||
return RNG.randomDouble(lowB, upB);
|
||||
}
|
||||
|
||||
///////////// Trivials...
|
||||
|
||||
public void SetIdentifier(String name) {
|
||||
m_Identifier = name;
|
||||
}
|
||||
|
||||
public InterfaceOptimizationProblem getProblem() {
|
||||
return problem;
|
||||
}
|
||||
|
||||
public String getStringRepresentation() {
|
||||
return "ScatterSearch";
|
||||
}
|
||||
|
||||
public void addPopulationChangedEventListener(
|
||||
InterfacePopulationChangedEventListener ea) {
|
||||
m_Listener = ea;
|
||||
}
|
||||
public boolean removePopulationChangedEventListener(
|
||||
InterfacePopulationChangedEventListener ea) {
|
||||
if (m_Listener==ea) {
|
||||
m_Listener=null;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
public void freeWilly() {}
|
||||
|
||||
public String getIdentifier() {
|
||||
return m_Identifier;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return "ScatterSearch";
|
||||
}
|
||||
|
||||
public static String globalInfo() {
|
||||
return "A scatter search variant after Rodiguez-Fernandez, J.Egea and J.Banga: Novel metaheuristic for parameter estimation in nonlinear dynamic biological systems, BMC Bioinf. 2006";
|
||||
}
|
||||
|
||||
private boolean useLSHC() {
|
||||
return localSearchMethod.getSelectedTagID()==0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the doLocalSearch
|
||||
*/
|
||||
public boolean isDoLocalSearch() {
|
||||
return doLocalSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param doLocalSearch the doLocalSearch to set
|
||||
*/
|
||||
public void setDoLocalSearch(boolean doLocalSearch) {
|
||||
this.doLocalSearch = doLocalSearch;
|
||||
setLSShowProps();
|
||||
}
|
||||
|
||||
private void setLSShowProps() {
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "localSearchFitnessFilter", doLocalSearch);
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "localSearchSteps", doLocalSearch);
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "nelderMeadInitPerturbation", doLocalSearch && !useLSHC());
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "localSearchRelativeFilter", doLocalSearch);
|
||||
GenericObjectEditor.setShowProperty(this.getClass(), "localSearchMethod", doLocalSearch);
|
||||
}
|
||||
|
||||
public String doLocalSearchTipText() {
|
||||
return "Perform a local search step";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the refSetSize
|
||||
*/
|
||||
public int getRefSetSize() {
|
||||
return refSetSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param refSetSize the refSetSize to set
|
||||
*/
|
||||
public void setRefSetSize(int refSetSize) {
|
||||
this.refSetSize = refSetSize;
|
||||
}
|
||||
|
||||
public String refSetSizeTipText() {
|
||||
return "Size of the reference set from which new candidates are created (similar to population size)";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the localSearchSteps
|
||||
*/
|
||||
public int getLocalSearchSteps() {
|
||||
return localSearchSteps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localSearchSteps the localSearchSteps to set
|
||||
*/
|
||||
public void setLocalSearchSteps(int localSearchSteps) {
|
||||
this.localSearchSteps = localSearchSteps;
|
||||
}
|
||||
|
||||
public String localSearchStepsTipText() {
|
||||
return "Define the number of evaluations performed for one local search.";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the localSearchFitnessFilter
|
||||
*/
|
||||
public double getLocalSearchFitnessFilter() {
|
||||
return localSearchFitnessFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localSearchFitnessFilter the localSearchFitnessFilter to set
|
||||
*/
|
||||
public void setLocalSearchFitnessFilter(double localSearchFitnessFilter) {
|
||||
this.localSearchFitnessFilter = localSearchFitnessFilter;
|
||||
}
|
||||
|
||||
public String localSearchFitnessFilterTipText() {
|
||||
return "Local search is performed only if the fitness is better than this value (absolute crit) or by this factor * (worst-best) fitness (relative).";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////7
|
||||
|
||||
/**
|
||||
* This method performs a scatter search runnable.
|
||||
*/
|
||||
public static final OptimizerRunnable createScatterSearch(
|
||||
int localSearchSteps, double localSearchFitnessFilter,
|
||||
double nmInitPerturb, boolean relativeFitCrit,
|
||||
int refSetSize,
|
||||
InterfaceTerminator term, String dataPrefix,
|
||||
AbstractOptimizationProblem problem, InterfacePopulationChangedEventListener listener) {
|
||||
|
||||
// problem.initProblem();
|
||||
|
||||
GOParameters params = specialSS(localSearchSteps, localSearchFitnessFilter, nmInitPerturb, relativeFitCrit, refSetSize, problem, term);
|
||||
|
||||
OptimizerRunnable rnbl = new OptimizerRunnable(params, dataPrefix);
|
||||
return rnbl;
|
||||
}
|
||||
|
||||
public static final GOParameters standardSS(
|
||||
AbstractOptimizationProblem problem) {
|
||||
return specialSS(0, 0, 0.1, true, 10, problem, new EvaluationTerminator(10000));
|
||||
}
|
||||
|
||||
public static final GOParameters specialSS(
|
||||
int localSearchSteps, double localSearchFitnessFilter,
|
||||
double nmInitPerturb, boolean relativeFitCrit,
|
||||
int refSetSize,
|
||||
AbstractOptimizationProblem problem, InterfaceTerminator term) {
|
||||
ScatterSearch ss = new ScatterSearch();
|
||||
problem.initProblem();
|
||||
ss.SetProblem(problem);
|
||||
ss.setRefSetSize(refSetSize);
|
||||
ss.setNelderMeadInitPerturbation(nmInitPerturb);
|
||||
ss.setLocalSearchRelativeFilter(relativeFitCrit);
|
||||
if (localSearchSteps > 0) {
|
||||
ss.setDoLocalSearch(true);
|
||||
ss.setLocalSearchSteps(localSearchSteps);
|
||||
ss.setLocalSearchFitnessFilter(localSearchFitnessFilter);
|
||||
} else ss.setDoLocalSearch(false);
|
||||
Population pop = new Population();
|
||||
pop.setTargetSize(refSetSize);
|
||||
pop.init();
|
||||
problem.initPopulation(pop);
|
||||
ss.initByPopulation(pop, true);
|
||||
|
||||
return OptimizerFactory.makeParams(ss, pop, problem, 0, term);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the relativeFitCriterion
|
||||
*/
|
||||
public boolean isLocalSearchRelativeFilter() {
|
||||
return relativeFitCriterion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param relativeFitCriterion the relativeFitCriterion to set
|
||||
*/
|
||||
public void setLocalSearchRelativeFilter(boolean relativeFitCriterion) {
|
||||
this.relativeFitCriterion = relativeFitCriterion;
|
||||
}
|
||||
|
||||
public String localSearchRelativeFilterTipText() {
|
||||
return "If selected, local search will be triggered by relative fitness, else by absolute";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the nelderMeadInitPerturbation
|
||||
*/
|
||||
public double getNelderMeadInitPerturbation() {
|
||||
return nelderMeadInitPerturbation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param nelderMeadInitPerturbation the nelderMeadInitPerturbation to set
|
||||
*/
|
||||
public void setNelderMeadInitPerturbation(double nelderMeadInitPerturbation) {
|
||||
this.nelderMeadInitPerturbation = nelderMeadInitPerturbation;
|
||||
}
|
||||
|
||||
public String nelderMeadInitPerturbationTipText() {
|
||||
return "The relative range of the initial perturbation for creating the initial Nelder-Mead-Simplex";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the localSearchMethod
|
||||
*/
|
||||
public SelectedTag getLocalSearchMethod() {
|
||||
return localSearchMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param localSearchMethod the localSearchMethod to set
|
||||
*/
|
||||
public void setLocalSearchMethod(SelectedTag localSearchMethod) {
|
||||
this.localSearchMethod = localSearchMethod;
|
||||
setLSShowProps();
|
||||
}
|
||||
|
||||
public String localSearchMethodTipText() {
|
||||
return "The local search method to use";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the poolSize
|
||||
*/
|
||||
public int getPoolSize() {
|
||||
return poolSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param poolSize the poolSize to set
|
||||
*/
|
||||
public void setPoolSize(int poolSize) {
|
||||
this.poolSize = poolSize;
|
||||
}
|
||||
|
||||
public String poolSizeTipText() {
|
||||
return "The number of individuals created in the diversification step";
|
||||
}
|
||||
|
||||
public double getImprovementEpsilon() {
|
||||
return improvementEpsilon;
|
||||
}
|
||||
public void setImprovementEpsilon(double improvementEpsilon) {
|
||||
this.improvementEpsilon = improvementEpsilon;
|
||||
}
|
||||
public String improvementEpsilonTipText() {
|
||||
return "Minimal relative fitness improvement for a candidate to enter the refSet - set to zero to deactivate.";
|
||||
}
|
||||
|
||||
public double getMinDiversityEpsilon() {
|
||||
return minDiversityEpsilon;
|
||||
}
|
||||
public void setMinDiversityEpsilon(double minDiversityEpsilon) {
|
||||
this.minDiversityEpsilon = minDiversityEpsilon;
|
||||
}
|
||||
public String minDiversityEpsilonTipText() {
|
||||
return "Minimal distance to other individuals in the refSet for a candidate to enter the refSet - set to zero to deactivate.";
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user