1061 lines
47 KiB
Java
1061 lines
47 KiB
Java
package eva2.optimization.strategies;
|
||
|
||
import eva2.OptimizerFactory;
|
||
import eva2.gui.editor.GenericObjectEditor;
|
||
import eva2.optimization.OptimizationParameters;
|
||
import eva2.optimization.enums.PSOTopology;
|
||
import eva2.optimization.individuals.AbstractEAIndividual;
|
||
import eva2.optimization.individuals.InterfaceDataTypeDouble;
|
||
import eva2.optimization.operator.nichepso.deactivation.StandardDeactivationStrategy;
|
||
import eva2.optimization.operator.paramcontrol.LinearParamAdaption;
|
||
import eva2.optimization.operator.paramcontrol.ParamAdaption;
|
||
import eva2.optimization.operator.terminators.EvaluationTerminator;
|
||
import eva2.optimization.operator.terminators.InterfaceTerminator;
|
||
import eva2.optimization.population.Population;
|
||
import eva2.optimization.population.PopulationInterface;
|
||
import eva2.problems.AbstractOptimizationProblem;
|
||
import eva2.problems.Interface2DBorderProblem;
|
||
import eva2.problems.InterfaceAdditionalPopulationInformer;
|
||
import eva2.tools.ToolBox;
|
||
import eva2.tools.chart2d.DPoint;
|
||
import eva2.tools.chart2d.DPointSet;
|
||
|
||
import java.util.Iterator;
|
||
import java.util.List;
|
||
import java.util.Set;
|
||
import java.util.Vector;
|
||
|
||
/**
|
||
* The Adaptive Niching PSO(ANPSO)[1] extends the particle swarm optimizer (PSO)
|
||
* by Kennedy and Eberhart to locate multiple optima of a multimodal objective function.
|
||
* The Algorithm uses similar concepts as the NichePSO such as a main swarm to explore
|
||
* the search space and subswarms to refine and represent single niches.
|
||
* The implemented version uses the "inertness weight" PSO to train the main swarm.
|
||
* mainSwarmInertness sets the inertia weight omega and weights the particles tendency to follow its former movement.
|
||
* This controls exploration (favored by larger values) against exploitation (favored by smaller values).
|
||
* mainSwarmPhi1 sets Phi1 and weights the cognitive component.
|
||
* The term corresponds to the particles tendency to return to its personal best position.
|
||
* mainSwarmPhi2 sets Phi2 and weights the social component.
|
||
* The term corresonds to the particles tendency to be attracted towards its neighborhood best position.
|
||
* A small value for mainSwarmPhi2 reduces the influence of the neighborhood and each particle tend to
|
||
* perfom a local search on its own. This results in a high exploration ability of the main swarm and
|
||
* potentially leads to a good amount of identified optima.
|
||
* Larger values for mainSwarmPhi2 on the other hand might help to concentrate on fewer optima with superior fitness values.
|
||
* <p>
|
||
* To avoid further parameters and the need to specify adequate values, which are often difficult to decide,
|
||
* the following adaption mechanism is employed:
|
||
* ANPSO adaptively determines a threshold parameter r during every generation by computing the average
|
||
* distance a particle has to its neighbor. Subsequently, a so called s-matrix is calculated that keeps
|
||
* track of how long any two particles are close (i.e. within r) to each other.
|
||
* The s-matrix is used to build a niche graph that represents particles as vertices and connects all particles
|
||
* that have been close to each other for at least two consecutive generations.
|
||
* Particles that are connected in the niche graph form a subswarm.
|
||
* The implemented version uses a strategy to deactivate subswarms when all containing particles converged on a solution.
|
||
* Furthermore, different neighborhood topologies can be choosen for the main swarm.
|
||
* In case the Multi-Swarm topology is used, the species radius is adaptively determined as well.
|
||
* <p>
|
||
* [1] S. Bird and X. Li:
|
||
* Adaptively choosing niching parameters in a PSO.
|
||
* In: GECCO '06: Proceedings of the 8th annual conference on Genetic and evolutionary computation,
|
||
* Seiten 3--10, New York, NY, USA, 2006. ACM
|
||
*
|
||
* @author aschoff, mkron
|
||
*/
|
||
public class ANPSO extends NichePSO implements InterfaceAdditionalPopulationInformer, java.io.Serializable {
|
||
|
||
|
||
/**
|
||
* *******************************************************************************************************************
|
||
* members
|
||
*/
|
||
// for ANPSO it is necessary to keep an own archiv of inactive subswarms, because the standard set of
|
||
// subswarms is completely renewed every iteration.
|
||
public Vector<ParticleSubSwarmOptimization> inactiveSubSwarms = new Vector<>();
|
||
|
||
// the s matrix keeps track of how long particles are close to each other
|
||
int[][] s = new int[mainSwarmSize][mainSwarmSize];
|
||
|
||
// the niche graph represents particles as vertices and connects all particles that
|
||
// have been close to each other for at least two consecutive generations
|
||
protected NicheGraph nicheGraph = new NicheGraph();
|
||
|
||
// defines the minimal distance for neighboring particles at which they form a subswarm
|
||
// (this is proposed by Bird and Lee for further investigation)
|
||
protected double minimalR = 0;
|
||
private double updateRadius = 0.;
|
||
// maximum subswarm size
|
||
private int maxInitialSubSwarmSize = 0;
|
||
|
||
private int maxNeighborCntNicheGraph = 4; // maximum for neighborhood matrix
|
||
private int minNeighborCntNicheGraph = 0; // minimum for neighborhood matrix
|
||
private int neighborCntNicheGraphForEdge = 2; // number of steps req. to build an edge
|
||
|
||
/**
|
||
* *******************************************************************************************************************
|
||
* ctors, clone
|
||
*/
|
||
public ANPSO() {
|
||
// NichePSO.stdNPSO(anpso, problem, randSeed, evalCnt);
|
||
// NichePSO.stdNPSO((ANPSO)this, (AbstractOptimizationProblem)this.problem, 0, 1000);
|
||
|
||
/////////// from NichePSO
|
||
// super.initMainSwarm(); // not really necessary if initialize is called before optimization but this way initialize doesnt change the parameters of a newly constructed object
|
||
// super.initSubswarmOptimizerTemplate();
|
||
// setMergingStrategy(new StandardMergingStrategy(0.001));
|
||
// setAbsorptionStrategy(new StandardAbsorptionStrategy());
|
||
// setSubswarmCreationStrategy(new StandardSubswarmCreationStrategy(0.0001));
|
||
//
|
||
// setMaxAllowedSwarmRadius(0.0001); // formally limits the swarm radius of the subswarms
|
||
|
||
// Parameter for the mainswarm
|
||
// npso.getMainSwarm().setSpeedLimit(avgRange/2.);
|
||
// npso.getMainSwarm().setCheckSpeedLimit(true);
|
||
|
||
// parameter for the subswarms
|
||
// System.out.println(BeanInspector.niceToString(getSubswarmOptimizerTemplate()));
|
||
// getSubswarmOptimizerTemplate().setGcpso(true);
|
||
// getSubswarmOptimizerTemplate().setRho(0.1); // on 2D Problems empirically better than default value 1
|
||
// getSubswarmOptimizerTemplate().setAlgoType(new SelectedTag("Constriction"));
|
||
// getSubswarmOptimizerTemplate().setConstriction(2.05, 2.05);
|
||
// System.out.println(BeanInspector.niceToString(getSubswarmOptimizerTemplate()));
|
||
|
||
///////////end from NichePSO
|
||
getMainSwarm().setPhi1(2.05);
|
||
getMainSwarm().setPhi2(2.05);
|
||
getMainSwarm().setInertnessOrChi(0.7298437881283576);
|
||
getMainSwarm().setAlgoType(ParticleSwarmOptimization.PSOType.Constriction);
|
||
setMainSwarmAlgoType(ParticleSwarmOptimization.PSOType.Constriction); // constriction
|
||
setMaxInitialSubSwarmSize(0); // deactivate early reinits
|
||
setMainSwarmTopology(PSOTopology.grid);
|
||
setMainSwarmTopologyRange(1);
|
||
setDeactivationStrategy(new StandardDeactivationStrategy(0.000001, 8));
|
||
setMainSwarmSize(100);
|
||
}
|
||
|
||
/*public ANPSO(){
|
||
// Parameter for the mainswarm
|
||
// //Earlier standard settings:
|
||
// this.setMainSwarmAlgoType(getMainSwarm().getAlgoType().setSelectedTag("Inertness"));
|
||
// this.mainSwarmPhi1 = 1.2;
|
||
// this.mainSwarmPhi2 = 0.6; // ANPSO uses communication in the main swarm
|
||
// this.mainSwarmTopology = PSOTopologyEnum.multiSwarm; //"Multi-Swarm" favors the formation of groups in the main swarm
|
||
// this.mainSwarmTopologyRange = 2; // range for topologies like random, grid etc. (does not affect "Multi-Swarm")
|
||
// this.setMainSwarmInertness(new NoParameterAging(0.73));
|
||
this.setMainSwarmPhi1(2.05);
|
||
this.setMainSwarmPhi2(2.05);
|
||
this.setMainSwarmInertness(new NoParameterAging(0.7298437881283576));
|
||
this.setMainSwarmAlgoType(getMainSwarm().getAlgoType().setSelectedTag("Constriction")); // constriction
|
||
this.setMaxInitialSubSwarmSize(0); // deactivate early reinits
|
||
this.setMainSwarmTopology(PSOTopologyEnum.grid);
|
||
this.setMainSwarmTopologyRange(1);
|
||
this.setDeactivationStrategy(new StandardDeactivationStrategy(0.000001, 8));
|
||
|
||
hideHideable();
|
||
initMainSwarm();
|
||
}*/
|
||
|
||
public ANPSO(int mainSwarmSize, double phi1, double phi2, PSOTopology mainSwarmTopo, int mainSwarmTopoRange, int maxInitialSubSwarmSize) {
|
||
this();
|
||
setMainSwarmSize(mainSwarmSize);
|
||
getMainSwarm().setPhi1(phi1);
|
||
getMainSwarm().setPhi2(phi2);
|
||
// setMainSwarmPhi1(phi1);
|
||
// setMainSwarmPhi2(phi2);
|
||
setMainSwarmTopologyRange(mainSwarmTopoRange);
|
||
setMainSwarmTopology(mainSwarmTopo);
|
||
setMaxInitialSubSwarmSize(maxInitialSubSwarmSize);
|
||
}
|
||
|
||
/**
|
||
* Take care that all properties which may be hidden (and currently are) send a "hide" message to the Java Bean properties.
|
||
* This is called by PropertySheetPanel in use with the GenericObjectEditor.
|
||
*/
|
||
@Override
|
||
public void hideHideable() {
|
||
// hide the following unused properties from the GUI
|
||
GenericObjectEditor.setHideProperty(getClass(), "subswarmCreationStrategy", true);
|
||
GenericObjectEditor.setHideProperty(getClass(), "mergingStrategy", true);
|
||
GenericObjectEditor.setHideProperty(getClass(), "absorptionStrategy", true);
|
||
GenericObjectEditor.setHideProperty(getClass(), "maxAllowedSwarmRadius", true);
|
||
GenericObjectEditor.setHideProperty(getClass(), "mainSwarmTopologyRange", mainSwarmTopology == PSOTopology.multiSwarm); // "Multi-Swarm" has no topologyRange
|
||
|
||
// population size is set via setMainSwarmSize
|
||
GenericObjectEditor.setHideProperty(getClass(), "population", true);
|
||
// setGOEShowProperties(getClass());
|
||
}
|
||
|
||
public ANPSO(ANPSO o) {
|
||
super(o);
|
||
this.inactiveSubSwarms = (Vector<ParticleSubSwarmOptimization>) o.inactiveSubSwarms.clone();
|
||
this.s = new int[mainSwarmSize][mainSwarmSize];
|
||
for (int i = 0; i < s.length; ++i) {
|
||
System.arraycopy(o.s[i], 0, s[i], 0, s[i].length);
|
||
}
|
||
|
||
this.nicheGraph = (NicheGraph) nicheGraph.clone();
|
||
this.minimalR = o.minimalR;
|
||
this.minNeighborCntNicheGraph = o.minNeighborCntNicheGraph;
|
||
this.maxNeighborCntNicheGraph = o.maxNeighborCntNicheGraph;
|
||
this.neighborCntNicheGraphForEdge = o.neighborCntNicheGraphForEdge;
|
||
}
|
||
|
||
@Override
|
||
public Object clone() {
|
||
return new ANPSO(this);
|
||
}
|
||
|
||
/**
|
||
* *******************************************************************************************************************
|
||
* inits
|
||
*/
|
||
@Override
|
||
public void initialize() { // MOE: wird vor Optimierung / n<>chstem multirun 1x aufgerufen
|
||
super.initialize();
|
||
initMainSwarm();
|
||
initSTo(0);
|
||
initNicheGraph();
|
||
|
||
inactiveSubSwarms = new Vector<>(); // dont want to use subswarms from old optimization run (especially not in multiruns)...
|
||
}
|
||
|
||
/**
|
||
* resets all entries of the s matrix that correspond to any
|
||
* particle in the given subswarm
|
||
*
|
||
* @param subswarm
|
||
*/
|
||
private void resetSMatrixEntriesFor(ParticleSubSwarmOptimization subswarm) {
|
||
Population pop = subswarm.getPopulation();
|
||
for (int i = 0; i < pop.size(); ++i) {
|
||
//Integer index = pop.getEAIndividual(i).getIndividualIndex();(Integer)pop.getEAIndividual(i).getData("particleIndex");
|
||
resetSMatrixForIndex(pop.getEAIndividual(i).getIndividualIndex(), 0);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* sets the given row and column to the given value
|
||
* (i.e. all entries corresponding to a specific particle)
|
||
*
|
||
* @param index
|
||
* @param val
|
||
*/
|
||
private void resetSMatrixForIndex(int index, int val) {
|
||
for (int i = 0; i < s.length; ++i) {
|
||
for (int j = 0; j < s[i].length; ++j) {
|
||
if (i == index || j == index) {
|
||
s[i][j] = val;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* sets every entry of the s matrix to the given value
|
||
*
|
||
* @param val
|
||
*/
|
||
private void initSTo(int val) {
|
||
for (int i = 0; i < s.length; ++i) {
|
||
for (int j = 0; j < s[i].length; ++j) {
|
||
s[i][j] = val;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* this inits the "niche graph".
|
||
* Every particle is represented as a vertex in the "niche graph".
|
||
*/
|
||
private void initNicheGraph() {
|
||
nicheGraph = new NicheGraph();
|
||
Population activePop = getActivePopulation();
|
||
for (int i = 0; i < activePop.size(); ++i) {
|
||
//Integer index = activePop.getEAIndividual(i).getParticleIndex();//(Integer)activePop.getEAIndividual(i).getData("particleIndex");
|
||
String vertex = "" + activePop.getEAIndividual(i).getIndividualIndex();
|
||
nicheGraph.addVertex(vertex);
|
||
}
|
||
}
|
||
|
||
/**********************************************************************************************************************
|
||
* ANPSO core
|
||
|
||
// /**
|
||
// * @param pop
|
||
// * @param normalized use a normalized metric to compute distances?
|
||
// * @return ave distance to neighbor in the given population
|
||
// */
|
||
// public double getAveDistToClosestNeighbor(Population pop, boolean normalized){
|
||
// PhenotypeMetric metric = new PhenotypeMetric();
|
||
//// ArrayList<Double> distances = new ArrayList<Double>(pop.size());
|
||
// double sum = 0;
|
||
// double d=0;
|
||
// for (int i = 0; i < pop.size(); ++i){
|
||
// AbstractEAIndividual neighbor, indy = pop.getEAIndividual(i);
|
||
// int neighborIndex = pop.getNeighborIndex(indy);
|
||
// if (neighborIndex >= 0) neighbor = pop.getEAIndividual(neighborIndex);
|
||
// else return -1;
|
||
// if (normalized){
|
||
// d = metric.distance(indy, neighbor);
|
||
// } else {
|
||
// d = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(indy),
|
||
// AbstractEAIndividual.getDoublePosition(neighbor));
|
||
// }
|
||
//// distances.add(d);
|
||
// sum += d;
|
||
// }
|
||
// double avg = sum/(double)pop.size();
|
||
//// if (normalized && (pop.getGeneration()==1)) {
|
||
//// double var = 0;
|
||
//// for (int i=0; i<distances.size(); i++) {
|
||
//// var += Math.pow(distances.get(i)-avg, 2);
|
||
//// }
|
||
//// System.out.println("gen " + pop.getGeneration() + " dim " + ((AbstractProblemDouble)problem).getProblemDimension() +" avg " + avg + " variance " + var);
|
||
//// }
|
||
// return avg;
|
||
// }
|
||
|
||
//
|
||
// /**
|
||
// * @param pop
|
||
// * @param indy
|
||
// * @return closest neighbor (euclidian measure) of the given individual in the given population
|
||
// */
|
||
// private AbstractEAIndividual getNeighbor(Population pop, AbstractEAIndividual indy) {
|
||
// if (pop.size() < 2){
|
||
// System.out.println("getNeighbor: swarm empty or indy only particle");
|
||
// return null;
|
||
// }
|
||
//
|
||
// // get the neighbor...
|
||
// int index = -1;
|
||
// double mindist = Double.POSITIVE_INFINITY;
|
||
//
|
||
// for (int i = 0; i < pop.size(); ++i){
|
||
// AbstractEAIndividual currentindy = pop.getEAIndividual(i);
|
||
// if (!indy.equals(currentindy)){ // dont compare particle to itself or a copy of itself
|
||
// double dist = getMainSwarm().distance(indy,currentindy);
|
||
// if (dist < mindist){
|
||
// mindist = dist;
|
||
// index = i;
|
||
// }
|
||
// }
|
||
// }
|
||
// if (index == -1){
|
||
// System.out.println("getNeighbor: all individuals in population are equal !?");
|
||
// return null;
|
||
// }
|
||
// return pop.getEAIndividual(index);
|
||
// }
|
||
|
||
/**
|
||
* Builds the s matrix and the niche graph.
|
||
* The s matrix keeps track of the number of generations
|
||
* each particle has been close to every other particle.
|
||
* The niche graph connects particles that have been close
|
||
* for at least two consecutive generations.
|
||
*/
|
||
public void updateSMatrixAndNicheGraph() {
|
||
// initialize the niche graph (all particles as vertices, no edges):
|
||
initNicheGraph();
|
||
|
||
// compute population statistic for parameter r:
|
||
Population metapop = getActivePopulation();
|
||
if (metapop.size() < 2) {
|
||
// this might happen if all but a single individual are scheduled to be reinitialized after species convergence
|
||
// System.err.println("Warning, active population of size " + metapop.size() +", radius will not be updated...");
|
||
} else {
|
||
updateRadius = metapop.getAvgDistToClosestNeighbor(false, false)[0];
|
||
} // use all particles not mainswarm particles only...
|
||
if (isVerbose()) {
|
||
System.out.print(" radius is " + updateRadius);
|
||
}
|
||
|
||
// build the s matrix and add edges to the niche graph:
|
||
// get particles i and j (unique in all swarms)...
|
||
AbstractEAIndividual[] sortedPop = sortActivePopByParticleIndex(); // sort once to reduce cpu-time spend for accessing members...
|
||
// System.out.println("metapop size is " + metapop.size());
|
||
for (int i = 0; i < s.length - 1; ++i) {
|
||
AbstractEAIndividual indy_i = sortedPop[i];
|
||
if (indy_i == null) {
|
||
continue;
|
||
} // may happen is some sub swarm was deactivated and the indies are scheduled for reinit
|
||
for (int j = i + 1; j < s[i].length; ++j) {
|
||
// call hotspot
|
||
AbstractEAIndividual indy_j = sortedPop[j];
|
||
if (indy_j == null) {
|
||
continue;
|
||
} // may happen is some sub swarm was deactivated and the indies are scheduled for reinit
|
||
if (indy_i == null || indy_j == null) {
|
||
System.out.println("updateSMatrixAndNicheGraph: indices problem");
|
||
}
|
||
|
||
// ...check if they are "close to each other"
|
||
double dist = getMainSwarm().distance(indy_i, indy_j);
|
||
if (dist < updateRadius || dist < minimalR) {
|
||
// increment entry that counts the number of generations
|
||
// i and j have been close to each other
|
||
++s[i][j];
|
||
|
||
// values must not exceed 4 to allow a particle to leave a niche
|
||
// in case it is further than r for two consecutive steps
|
||
if (s[i][j] > maxNeighborCntNicheGraph) {
|
||
s[i][j] = maxNeighborCntNicheGraph;
|
||
}
|
||
|
||
// if i and j had been close to each other for at least two generations
|
||
// they are connected by an edge
|
||
if (s[i][j] >= neighborCntNicheGraphForEdge) {
|
||
String pi = "" + i;
|
||
String pj = "" + j;
|
||
nicheGraph.addEdge(pi, pj);
|
||
}
|
||
} else {
|
||
// decrement entry that counts the number of generations
|
||
// i and j have been close to each other
|
||
--s[i][j];
|
||
if (s[i][j] < minNeighborCntNicheGraph) {
|
||
s[i][j] = minNeighborCntNicheGraph;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The returned array may contain null entries (for indies scheduled for reinitialization).
|
||
*
|
||
* @return an array of references sorted according to the particle indices
|
||
* (i.e. returnedArray[i] = individual with individualIndex i)
|
||
*/
|
||
protected AbstractEAIndividual[] sortActivePopByParticleIndex() {
|
||
Population pop = getActivePopulation();
|
||
AbstractEAIndividual[] sorted;
|
||
if (pop.size() < mainSwarmSize) {
|
||
int reinitSize = 0;
|
||
if (indicesToReinit != null) {
|
||
for (int i = 0; i < indicesToReinit.size(); i++) {
|
||
reinitSize += indicesToReinit.get(i).length;
|
||
}
|
||
}
|
||
if (pop.size() + reinitSize == mainSwarmSize) { // good case, extend pop size; null entries are to be tolerated.
|
||
sorted = new AbstractEAIndividual[pop.size() + reinitSize];
|
||
} else {
|
||
throw new RuntimeException("Error, invalid size of active population (ANPSO.sortActivePopByParticleIndex()");
|
||
}
|
||
} else {
|
||
sorted = new AbstractEAIndividual[pop.size()];
|
||
}
|
||
for (int i = 0; i < pop.size(); ++i) {
|
||
AbstractEAIndividual indy = pop.getEAIndividual(i);
|
||
if (sorted[indy.getIndividualIndex()] != null) {
|
||
System.err.println("error in sortByParticleIndex!");
|
||
}
|
||
if (sorted[indy.getIndividualIndex()] != null) {
|
||
throw new RuntimeException("Error, inconsistency in ANPSO! (index wrong)");
|
||
}
|
||
sorted[indy.getIndividualIndex()] = indy;
|
||
}
|
||
return sorted;
|
||
}
|
||
|
||
|
||
/**
|
||
* uses the sets of particles as different subswarms and removes the particles from the mainswarm
|
||
*
|
||
* @param setOfSubswarms
|
||
*/
|
||
public void useAsSubSwarms(Vector<Population> setOfSubswarms) {
|
||
Vector<ParticleSubSwarmOptimization> newSubSwarms = new Vector<>();
|
||
|
||
for (int i = 0; i < setOfSubswarms.size(); ++i) {
|
||
Population pop = setOfSubswarms.get(i);
|
||
ParticleSubSwarmOptimization subswarm = getNewSubSwarmOptimizer();
|
||
subswarm.getPopulation().clear();
|
||
subswarm.getPopulation().addAll(pop);
|
||
subswarm.populationSizeHasChanged();
|
||
newSubSwarms.add(subswarm);
|
||
getMainSwarm().removeSubPopulation(pop, true); // the new subswarm can also come from an earlier subswarm
|
||
getMainSwarm().populationSizeHasChanged();
|
||
}
|
||
if (isVerbose()) {
|
||
System.out.println();
|
||
for (int i = 0; i < newSubSwarms.size(); i++) {
|
||
System.out.println("Swarm " + i + " (" + newSubSwarms.get(i).getPopulation().size() + "), best " + newSubSwarms.get(i).getBestIndividual());
|
||
}
|
||
}
|
||
// add the function calls from the subswarms of the last iteration to the mainswarm before forgetting them
|
||
// the function calls from the inactivated subswarms are transfered to the mainswarm as well
|
||
// -> do not count them in getPopulation a second time
|
||
int calls = 0;
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
ParticleSubSwarmOptimization subswarm = getSubSwarms().get(i);
|
||
calls += subswarm.getPopulation().getFunctionCalls();
|
||
}
|
||
getMainSwarm().getPopulation().incrFunctionCallsBy(calls);
|
||
|
||
this.setSubSwarms(newSubSwarms);
|
||
}
|
||
|
||
/**
|
||
* uses the population as the mainswarm
|
||
*
|
||
* @param pop
|
||
*/
|
||
public void useAsMainSwarm(Population pop) {
|
||
int generations = getMainSwarm().getPopulation().getGeneration();
|
||
int calls = getMainSwarm().getPopulation().getFunctionCalls();
|
||
getMainSwarm().setPopulation(pop);
|
||
getMainSwarm().populationSizeHasChanged();
|
||
getMainSwarm().getPopulation().setGeneration(generations);
|
||
getMainSwarm().getPopulation().setFunctionCalls(calls);
|
||
}
|
||
|
||
/**
|
||
* creates subswarms from all particles that correspond to connected vertices in the niche graph.
|
||
* Particles corresponding to unconnected vertices belong to the mainswarm.
|
||
*/
|
||
public void createSubswarmsFromNicheGraph() {
|
||
// get all sets of vertices that are connected in the niche graph...
|
||
//(subSwarms = new Vector<ParticleSubSwarmOptimization>(); // too early, particles would be lost...
|
||
List<Set<String>> connectedComps = nicheGraph.getConnectedComponents();
|
||
|
||
Population tmpPop = new Population(), newMainPop = new Population();
|
||
Vector<Population> setOfSubswarms = new Vector<>();
|
||
boolean reinitSuperfl = true;
|
||
|
||
for (Set<String> connSet : connectedComps) {
|
||
if (connSet.size() > 1) {// create niche
|
||
Population pop = new Population(connSet.size());
|
||
for (String indexStr : connSet) {
|
||
Integer index = Integer.valueOf(indexStr);
|
||
AbstractEAIndividual indy = getIndyByParticleIndex(index); // may be taken from a main swarm or current subwarm
|
||
if (indy == null) {
|
||
System.err.println("createNichesFromNicheGraph problem -> getIndyByParticleIndex returned null");
|
||
}
|
||
pop.add(indy);
|
||
}
|
||
if (maxInitialSubSwarmSize > 0 && (pop.size() > maxInitialSubSwarmSize)) {
|
||
tmpPop = pop.getWorstNIndividuals(pop.size() - maxInitialSubSwarmSize, -1);
|
||
tmpPop.synchSize();
|
||
pop.removeMembers(tmpPop, true);
|
||
if (reinitSuperfl) {
|
||
for (int i = 0; i < tmpPop.size(); i++) {
|
||
AbstractEAIndividual indy = tmpPop.getEAIndividual(i);
|
||
indy.initialize(optimizationProblem);
|
||
indy.resetFitness(Double.MAX_VALUE); // TODO this is not so nice... they should be collected in a reinit-list and inserted at the beginning of the next optimize step
|
||
ParticleSwarmOptimization.initIndividualDefaults(indy, 0.2);
|
||
ParticleSwarmOptimization.initIndividualMemory(indy);
|
||
ParticleSubSwarmOptimization.initSubSwarmDefaultsOf(indy);
|
||
}
|
||
}
|
||
newMainPop.addPopulation(tmpPop);
|
||
pop.synchSize();
|
||
}
|
||
setOfSubswarms.add(pop);
|
||
} else { // move particles corresponding to unconnected vertices to the mainswarm
|
||
Iterator<String> it = connSet.iterator();
|
||
Integer index = Integer.valueOf(it.next());
|
||
AbstractEAIndividual indy = getIndyByParticleIndex(index);
|
||
newMainPop.add(indy);
|
||
}
|
||
}
|
||
|
||
newMainPop.synchSize();
|
||
for (Population setOfSubswarm : setOfSubswarms) {
|
||
setOfSubswarm.synchSize();
|
||
}
|
||
useAsSubSwarms(setOfSubswarms);
|
||
useAsMainSwarm(newMainPop);
|
||
}
|
||
|
||
/**
|
||
*/
|
||
@Override
|
||
public void optimize() {
|
||
// main swarm:
|
||
if (getMainSwarm().getPopulation().size() == 0) {// || mainSwarm.getPopulation().size() == 1){
|
||
if (isVerbose()) {
|
||
System.out.print("MainSwarm size is 0\n");
|
||
}
|
||
// increment the generationcount for the Terminator:
|
||
// 1 Generation equals one optimize call including the optimization of the
|
||
// (possibly empty) mainSwarm and all subSwarms
|
||
getMainSwarm().getPopulation().incrGeneration();
|
||
} else {
|
||
getMainSwarm().optimize();
|
||
}
|
||
maybeReinitIndies();
|
||
|
||
// sub swarms:
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
ParticleSubSwarmOptimization subswarm = getSubSwarms().get(i);
|
||
if (subswarm.isActive()) {
|
||
subswarm.optimize();
|
||
}
|
||
}
|
||
|
||
// deactivation:
|
||
deactivateSubSwarmsIfPossible();
|
||
|
||
if (isVerbose()) {
|
||
System.out.print("active swarms: " + countActiveSubswarms() + " of " + getSubSwarms().size());
|
||
}
|
||
|
||
// build the s matrix and the niche graph
|
||
// these data structures represent particles that have been close to each other
|
||
// for at least two consecutive generations
|
||
updateSMatrixAndNicheGraph();
|
||
|
||
// create subswarms from the particles corresponding to connected vertices in the niche graph
|
||
createSubswarmsFromNicheGraph();
|
||
|
||
// one might create additional subswarms from the main swarm
|
||
// using the standard strategie from the NichePSO
|
||
// createSubswarmIfPossible();
|
||
|
||
// adapt the species radius of the SPSO using similar population statistics as for the radius parameter r
|
||
if ((mainSwarm.getTopology() == PSOTopology.multiSwarm) && (mainSwarm.getMaxSubSwarmSize() > 1)) { //Multi-Swarm
|
||
double aveDistToNeighInMain = getMainSwarm().getPopulation().getAvgDistToClosestNeighbor(true, false)[0];
|
||
getMainSwarm().setSubSwarmRadius(aveDistToNeighInMain);
|
||
}
|
||
|
||
if (isVerbose()) {
|
||
System.out.println();
|
||
}
|
||
firePropertyChangedEvent("NextGenerationPerformed"); // calls Listener that sth changed...
|
||
|
||
/** plotting **********************************************************************************/
|
||
if (isPlot()) {
|
||
doPlot();
|
||
}
|
||
|
||
// reset flags etc for:
|
||
// deactivation
|
||
deactivationOccured = false;
|
||
deactivatedSwarm = new Vector<>();
|
||
// merging
|
||
mergingOccurd = false;
|
||
borg = new Vector<>();
|
||
others = new Vector<>();
|
||
borgbest = new Vector<>();
|
||
othersbest = new Vector<>();
|
||
// absorbtion
|
||
absorbtionOccurd = false;
|
||
indytoabsorb = new Vector<>();
|
||
// subswarmcreation
|
||
creationOccurd = false;
|
||
indyconverged = new Vector<>();
|
||
convergedneighbor = new Vector<>();
|
||
//clearing - deprecated
|
||
//reinitoccurd = false;
|
||
|
||
}
|
||
|
||
|
||
/**
|
||
* *******************************************************************************************************************
|
||
* Deactivation
|
||
*/
|
||
|
||
@Override
|
||
protected void deactivationEventFor(ParticleSubSwarmOptimization subswarm) {
|
||
super.deactivationEventFor(subswarm);
|
||
resetSMatrixEntriesFor(subswarm);
|
||
inactiveSubSwarms.add(subswarm); // ANPSO will later remove the inactive subswarm from the standard set of subswarms...
|
||
}
|
||
|
||
/**********************************************************************************************************************
|
||
* setter, getter
|
||
*/
|
||
/**
|
||
* @param size
|
||
* sets the !initial! size of the mainswarm population
|
||
* use this instead of getPopulation.setPopulationSize()
|
||
*/
|
||
@Override
|
||
public void setMainSwarmSize(int size) {
|
||
// set member
|
||
this.mainSwarmSize = size;
|
||
// pass on to the mainswarm optimizer
|
||
getMainSwarm().getPopulation().setTargetSize(size);
|
||
// update s
|
||
s = new int[size][size];
|
||
initSTo(0);
|
||
initNicheGraph();
|
||
}
|
||
|
||
/**
|
||
* @param includeInactive
|
||
* @return a population with clones from all subswarms
|
||
*/
|
||
public Population getSubswarmMetapop(boolean includeInactive) {
|
||
// construct a metapop with clones from all subswarms
|
||
Population metapop = new Population();
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
ParticleSubSwarmOptimization currentsubswarm = getSubSwarms().get(i);
|
||
if (includeInactive || currentsubswarm.isActive()) {
|
||
Population currentsubswarmpop = (Population) currentsubswarm.getPopulation().clone();
|
||
metapop.addPopulation(currentsubswarmpop);
|
||
}
|
||
}
|
||
return metapop;
|
||
}
|
||
|
||
/**
|
||
* @return a population consisting of copies from the mainswarm and all subswarms.
|
||
* returns a population consisting of copies from the mainswarm and all subswarms
|
||
* (active and inactive, so the size of this Population is not necessarily constant).
|
||
* Especially important for the call back regarding the output file...
|
||
* Beware: getPopulation().getPopulationSize() returns the !initial! size of the main swarm,
|
||
* the actual size of the complete population is accessed via getPopulation().size()
|
||
*/
|
||
@Override
|
||
public Population getPopulation() {
|
||
// construct a metapop with clones from the mainswarm and all subswarms
|
||
Population metapop = (Population) getMainSwarm().getPopulation().clone();
|
||
Population currentsubswarm = new Population();
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
currentsubswarm = (Population) getSubSwarms().get(i).getPopulation().clone();
|
||
metapop.addPopulation(currentsubswarm);
|
||
}
|
||
for (ParticleSubSwarmOptimization inactiveSubSwarm : inactiveSubSwarms) { // in the case of ANPSO
|
||
currentsubswarm = (Population) inactiveSubSwarm.getPopulation().clone();
|
||
metapop.addPopulation(currentsubswarm);
|
||
}
|
||
|
||
// set correct number of generations
|
||
metapop.setGeneration(getMainSwarm().getPopulation().getGeneration());
|
||
|
||
// set correct number of function calls
|
||
int calls = getMainSwarm().getPopulation().getFunctionCalls();
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
ParticleSubSwarmOptimization subswarm = getSubSwarms().get(i);
|
||
calls += subswarm.getPopulation().getFunctionCalls();
|
||
}
|
||
// calls from inactivated subswarms were transfered to the mainswarm, see useAsSubSwarms method
|
||
|
||
metapop.setFunctionCalls(calls);
|
||
|
||
return metapop;
|
||
}
|
||
|
||
/**
|
||
* @return array with copies of the gbest individuals
|
||
* returns the cloned global best individuals (ie best of all time) from every subswarm
|
||
*/
|
||
public Population getSubswarmRepresentatives() {
|
||
//boolean includeMainSwarm = false;
|
||
int mainSize = 0;
|
||
//if (includeMainSwarm) mainSize = getMainSwarm().getPopulation().size();
|
||
Population elitePop = new Population(getSubSwarms().size() + inactiveSubSwarms.size() + mainSize);
|
||
|
||
for (int i = 0; i < getSubSwarms().size(); ++i) {
|
||
AbstractEAIndividual bestSS = getSubSwarms().get(i).getBestIndividual();
|
||
elitePop.addIndividual((AbstractEAIndividual) getSubSwarms().get(i).bestIndividual.clone());
|
||
}
|
||
for (ParticleSubSwarmOptimization inactiveSubSwarm : inactiveSubSwarms) {
|
||
elitePop.addIndividual((AbstractEAIndividual) inactiveSubSwarm.bestIndividual.clone());
|
||
}
|
||
return elitePop;
|
||
}
|
||
|
||
/**
|
||
* @return descriptive string of the elite
|
||
* returns a string that lists the global best individuals (ie best of all time) from every subswarm
|
||
*/
|
||
public String getSubswarmRepresentativesAsString() {
|
||
String result = "\nSubswarmRepresentatives: \n";
|
||
Population elite = getSubswarmRepresentatives();
|
||
for (int i = 0; i < getSubSwarms().size() + inactiveSubSwarms.size(); ++i) {
|
||
result += elite.getEAIndividual(i).getStringRepresentation() + "\n";
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
*/
|
||
@Override
|
||
protected void plotSubSwarms() {
|
||
if (this.optimizationProblem instanceof Interface2DBorderProblem) {
|
||
//DPointSet popRep = new DPointSet();
|
||
InterfaceDataTypeDouble tmpIndy1;
|
||
|
||
//cleanPlotSubSwarms();
|
||
|
||
// for all inactive SubSwarms from ANPSO...
|
||
for (int i = 0; i < this.inactiveSubSwarms.size(); i++) {
|
||
ParticleSubSwarmOptimization currentsubswarm = this.inactiveSubSwarms.get(i);
|
||
InterfaceDataTypeDouble best = (InterfaceDataTypeDouble) currentsubswarm.bestIndividual;
|
||
plotCircleForIndy((AbstractEAIndividual) best, "[I]");
|
||
}
|
||
|
||
// for all SubSwarms...
|
||
for (int i = 0; i < this.getSubSwarms().size(); i++) {
|
||
ParticleSubSwarmOptimization currentsubswarm = this.getSubSwarms().get(i);
|
||
Population currentsubswarmpop = currentsubswarm.getPopulation();
|
||
//InterfaceDataTypeDouble best = (InterfaceDataTypeDouble)currentsubswarmpop.getBestIndividual();
|
||
InterfaceDataTypeDouble best = (InterfaceDataTypeDouble) currentsubswarm.bestIndividual;
|
||
DPointSet popRep = new DPointSet();
|
||
|
||
//...draw SubSwarm as points
|
||
for (int j = 0; j < currentsubswarmpop.size(); j++) {
|
||
popRep.setConnected(false);
|
||
tmpIndy1 = (InterfaceDataTypeDouble) currentsubswarmpop.get(j);
|
||
popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]));
|
||
}
|
||
this.topoPlot.getFunctionArea().addDElement(popRep); // time consuming
|
||
|
||
//...draw circle for best
|
||
if (!currentsubswarm.isActive()) {
|
||
plotCircleForIndy((AbstractEAIndividual) best, "[I]");
|
||
} else {
|
||
if (getSubswarmOptimizerTemplate().isGcpso()) {
|
||
String rhoAsString = String.format("%6.3f", currentsubswarm.getRho());
|
||
}
|
||
}
|
||
|
||
//...draw SubSwarm as connected lines to best
|
||
popRep = new DPointSet();
|
||
for (int j = 0; j < currentsubswarmpop.size(); j++) {
|
||
//popRep.setConnected(false);
|
||
tmpIndy1 = (InterfaceDataTypeDouble) currentsubswarmpop.get(j);
|
||
//popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]));
|
||
|
||
popRep.setConnected(true);
|
||
popRep.addDPoint(new DPoint(tmpIndy1.getDoubleData()[0], tmpIndy1.getDoubleData()[1]));
|
||
popRep.addDPoint(new DPoint(best.getDoubleData()[0], best.getDoubleData()[1]));
|
||
}
|
||
this.topoPlot.getFunctionArea().addDElement(popRep); // time consuming
|
||
}
|
||
} // endif
|
||
}
|
||
|
||
/**
|
||
* @param index
|
||
* @return inactive particles with given index
|
||
* (may return more than one particle for a given index because indizes are reused during deactivation
|
||
* and the reinitialized particle may be deactivated again...)
|
||
*/
|
||
public Vector<AbstractEAIndividual> getInactiveIndiesByParticleIndex(Integer index) {
|
||
Vector<AbstractEAIndividual> indies = null;
|
||
AbstractEAIndividual indy = null;
|
||
for (int i = 0; i < inactiveSubSwarms.size(); ++i) {
|
||
Population pop = inactiveSubSwarms.get(i).getPopulation();
|
||
indy = getIndyByParticleIndexAndPopulation(pop, index); // fix if needed: only returns the first occurence...
|
||
if (indy != null) {
|
||
indies.add(indy);
|
||
}
|
||
}
|
||
return indies;
|
||
}
|
||
|
||
/**
|
||
* @return The name of the algorithm
|
||
* This method will return a naming String
|
||
*/
|
||
@Override
|
||
public String getName() {
|
||
return "ANPSO-" + getMainSwarmSize();
|
||
}
|
||
|
||
public void SetMinimalR(double minimalR) {
|
||
this.minimalR = minimalR;
|
||
}
|
||
|
||
public int getMaxInitialSubSwarmSize() {
|
||
return maxInitialSubSwarmSize;
|
||
}
|
||
|
||
public String maxInitialSubSwarmSizeTipText() {
|
||
return "The maximum size of sub swarms at creation time.";
|
||
}
|
||
|
||
public void setMaxInitialSubSwarmSize(int maxSubSwarmSize) {
|
||
this.maxInitialSubSwarmSize = maxSubSwarmSize;
|
||
}
|
||
|
||
|
||
public String mainSwarmTopologyTipText() {
|
||
return "sets the topology type used to train the main swarm";
|
||
}
|
||
|
||
public String mainSwarmTopologyRangeTipText() {
|
||
return "sets the range of the neighborhood topology for the main swarm";
|
||
}
|
||
|
||
public static OptimizationParameters aNichePSO(AbstractOptimizationProblem problem, long randSeed, InterfaceTerminator term) {
|
||
ANPSO anpso = new ANPSO();
|
||
anpso.setMainSwarmSize(75);
|
||
|
||
return OptimizerFactory.makeParams(anpso, 75, problem, randSeed, term);
|
||
}
|
||
|
||
/**
|
||
* Creates a standard ANPSO variant with default constricted PSO parameters and a grid topology.
|
||
*
|
||
* @param problem
|
||
* @param randSeed
|
||
* @param evalCnt
|
||
* @return
|
||
*/
|
||
public static OptimizationParameters stdANPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) {
|
||
ANPSO anpso = new ANPSO();
|
||
NichePSO.stdNPSO(anpso, problem, randSeed, evalCnt);
|
||
|
||
anpso.getMainSwarm().setPhi1(2.05);
|
||
anpso.getMainSwarm().setPhi2(2.05);
|
||
anpso.getMainSwarm().setInertnessOrChi(0.7298437881283576);
|
||
anpso.getMainSwarm().setAlgoType(ParticleSwarmOptimization.PSOType.Constriction);
|
||
anpso.setMainSwarmAlgoType(ParticleSwarmOptimization.PSOType.Constriction); // constriction
|
||
anpso.setMaxInitialSubSwarmSize(0); // deactivate early reinits
|
||
anpso.setMainSwarmTopology(PSOTopology.grid);
|
||
anpso.setMainSwarmTopologyRange(1);
|
||
anpso.setDeactivationStrategy(new StandardDeactivationStrategy(0.000001, 8));
|
||
|
||
// es gibt kein species size limit wie im orig-paper, aber sie berichten dort, dass sie für
|
||
// höhere dimensionsn (3,4), eh keines benutzen.
|
||
|
||
return OptimizerFactory.makeParams(anpso, anpso.getMainSwarmSize(), problem, randSeed, new EvaluationTerminator(evalCnt));
|
||
}
|
||
|
||
public static OptimizationParameters starANPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) {
|
||
ANPSO anpso = new ANPSO();
|
||
NichePSO.starNPSO(anpso, problem, randSeed, evalCnt);
|
||
|
||
anpso.getMainSwarm().setParameterControl(new ParamAdaption[]{new LinearParamAdaption("inertnessOrChi", 0.7, 0.2)});
|
||
// anpso.setMainSwarmInertness(new LinearParameterAging(0.7, 0.2, evalCnt/anpso.getMainSwarmSize()));
|
||
|
||
anpso.getMainSwarm().setAlgoType(ParticleSwarmOptimization.PSOType.Inertness);
|
||
anpso.setMainSwarmAlgoType(ParticleSwarmOptimization.PSOType.Inertness); // inertness
|
||
anpso.getMainSwarm().setPhi1(1.2);
|
||
anpso.getMainSwarm().setPhi2(0.6); // ANPSO uses communication in the main swarm
|
||
//Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" in that order starting by 0.
|
||
anpso.setMainSwarmTopologyTag(3); //"Multi-Swarm" favors the formation of groups in the main swarm
|
||
anpso.setMainSwarmTopologyRange(2); // range for topologies like random, grid etc. (does not affect "Multi-Swarm")
|
||
anpso.setMaxInitialSubSwarmSize(0); // deactivate early reinits
|
||
|
||
// es gibt kein species size limit wie im orig-paper, aber sie berichten dort, dass sie für
|
||
// höhere dimensionsn (3,4), eh keines benutzen.
|
||
|
||
return OptimizerFactory.makeParams(anpso, anpso.getMainSwarmSize(), problem, randSeed, new EvaluationTerminator(evalCnt));
|
||
}
|
||
|
||
public static OptimizationParameters gmakANPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) {
|
||
ANPSO anpso = new ANPSO();
|
||
NichePSO.starNPSO(anpso, problem, randSeed, evalCnt);
|
||
|
||
anpso.getMainSwarm().setParameterControl(new ParamAdaption[]{new LinearParamAdaption("inertnessOrChi", 0.7, 0.2)});
|
||
|
||
anpso.getMainSwarm().setAlgoType(ParticleSwarmOptimization.PSOType.Inertness);
|
||
anpso.setMainSwarmAlgoType(ParticleSwarmOptimization.PSOType.Inertness);
|
||
anpso.getMainSwarm().setPhi1(1.2);
|
||
anpso.getMainSwarm().setPhi2(1.2); // ANPSO uses communication in the main swarm
|
||
//Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" in that order starting by 0.
|
||
anpso.setMainSwarmTopologyTag(3); //"Multi-Swarm" favors the formation of groups in the main swarm
|
||
anpso.setMainSwarmTopologyRange(4); // range for topologies like random, grid etc. (does not affect "Multi-Swarm")
|
||
|
||
// es gibt kein species size limit wie im orig-paper, aber sie berichten dort, dass sie für
|
||
// höhere dimensionsn (3,4), eh keines benutzen.
|
||
|
||
anpso.getSubswarmOptimizerTemplate().setRho(1);
|
||
anpso.getSubswarmOptimizerTemplate().SetRhoIncreaseFactor(2);
|
||
anpso.getSubswarmOptimizerTemplate().SetRhoDecreaseFactor(0.5);
|
||
|
||
return OptimizerFactory.makeParams(anpso, anpso.getMainSwarmSize(), problem, randSeed, new EvaluationTerminator(evalCnt));
|
||
}
|
||
|
||
/**
|
||
* Create a grid-star-ANPSO with range 2.
|
||
*
|
||
* @param problem
|
||
* @param randSeed
|
||
* @param evalCnt
|
||
* @return
|
||
*/
|
||
public static OptimizationParameters sgANPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt) {
|
||
return starTopoANPSO(problem, randSeed, evalCnt, 1, 2);
|
||
}
|
||
|
||
/**
|
||
* Create a starANPSO with a given main swarm topology.
|
||
*
|
||
* @param problem
|
||
* @param randSeed
|
||
* @param evalCnt
|
||
* @param topology
|
||
* @param topologyRange
|
||
* @return
|
||
*/
|
||
public static OptimizationParameters starTopoANPSO(AbstractOptimizationProblem problem, long randSeed, int evalCnt, int topology, int topologyRange) {
|
||
OptimizationParameters params = starANPSO(problem, randSeed, evalCnt);
|
||
((ANPSO) params.getOptimizer()).setMainSwarmTopologyTag(topology);
|
||
((ANPSO) params.getOptimizer()).setMainSwarmTopologyRange(topologyRange);
|
||
((ANPSO) params.getOptimizer()).getMainSwarm().setInertnessOrChi(0.73);
|
||
|
||
return params;
|
||
}
|
||
|
||
@Override
|
||
public String[] getAdditionalDataHeader() {
|
||
return ToolBox.appendArrays(super.getAdditionalDataHeader(), new String[]{"mainSwarmBestFit", "swarmRad"});
|
||
}
|
||
|
||
@Override
|
||
public Object[] getAdditionalDataValue(PopulationInterface pop) {
|
||
return ToolBox.appendArrays(super.getAdditionalDataValue(pop), new Object[]{getMainSwarm().getPopulation().getBestFitness()[0], updateRadius});
|
||
}
|
||
|
||
@Override
|
||
public String[] getAdditionalDataInfo() {
|
||
return ToolBox.appendArrays(super.getAdditionalDataInfo(), new String[]{"The best fitness within the main swarm", "The current value of the adapted swarm radius"});
|
||
}
|
||
|
||
@Override
|
||
public Population getSubswarmRepresentatives(boolean onlyInactive) {
|
||
|
||
Population representatives = super.getSubswarmRepresentatives(onlyInactive);
|
||
// this vector does not yet contain the archived solutions
|
||
for (int i = 0; i < inactiveSubSwarms.size(); i++) {
|
||
representatives.add(inactiveSubSwarms.get(i).getBestIndividual());
|
||
}
|
||
representatives.synchSize();
|
||
return representatives;
|
||
}
|
||
|
||
/**
|
||
* Return the median correlation of the best individuals of the given set of swarms.
|
||
*/
|
||
private double getMedCorrelation(
|
||
Vector<ParticleSubSwarmOptimization> swarms) {
|
||
Population pop = new Population(swarms.size());
|
||
for (int i = 0; i < swarms.size(); i++) {
|
||
if (swarms.get(i) != null) {
|
||
pop.addIndividual(swarms.get(i).getBestIndividual());
|
||
}
|
||
}
|
||
return pop.getCorrelations()[3];
|
||
}
|
||
|
||
/**
|
||
* Return the mean distance of the best individuals of the given set of swarms.
|
||
*
|
||
* @param swarms
|
||
* @return
|
||
*/
|
||
private double getMeanDist(
|
||
Vector<ParticleSubSwarmOptimization> swarms) {
|
||
Population pop = new Population(swarms.size());
|
||
for (int i = 0; i < swarms.size(); i++) {
|
||
if (swarms.get(i) != null) {
|
||
pop.addIndividual(swarms.get(i).getBestIndividual());
|
||
}
|
||
}
|
||
return pop.getPopulationMeasures()[0];
|
||
}
|
||
|
||
@Override
|
||
protected int getNumArchived() {
|
||
return (inactiveSubSwarms.size());
|
||
}
|
||
}
|