diff --git a/src/eva2/gui/GenericArrayEditor.java b/src/eva2/gui/GenericArrayEditor.java index c53d0d14..876287cc 100644 --- a/src/eva2/gui/GenericArrayEditor.java +++ b/src/eva2/gui/GenericArrayEditor.java @@ -260,8 +260,8 @@ public class GenericArrayEditor extends JPanel implements PropertyEditor { * @param valueClass The class of the array values */ public EditorListCellRenderer(Class editorClass, Class valueClass) { - editorClass = editorClass; - valueClass = valueClass; + this.editorClass = editorClass; + this.valueClass = valueClass; } /** @@ -282,12 +282,12 @@ public class GenericArrayEditor extends JPanel implements PropertyEditor { try { final PropertyEditor e = (PropertyEditor) editorClass.newInstance(); if (e instanceof GenericObjectEditor) { - // ((GenericObjectEditor) e).setDisplayOnly(true); ((GenericObjectEditor) e).setClassType(valueClass); } e.setValue(value); JPanel cellPanel = new JPanel() { + @Override public void paintComponent(Graphics g) { Insets i = this.getInsets(); Rectangle box = new Rectangle(i.left, i.top, @@ -299,6 +299,7 @@ public class GenericArrayEditor extends JPanel implements PropertyEditor { e.paintValue(g, box); } + @Override public Dimension getPreferredSize() { Font f = this.getFont(); FontMetrics fm = this.getFontMetrics(f); @@ -364,7 +365,7 @@ public class GenericArrayEditor extends JPanel implements PropertyEditor { // Create the ListModel and populate it listModel = new DefaultListModel(); - elementClass = elementClass; + this.elementClass = elementClass; for (int i = 0; i < Array.getLength(arrayInstance); i++) { listModel.addElement(Array.get(arrayInstance, i)); } diff --git a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java index 01caafb9..f6e34986 100644 --- a/src/eva2/server/go/strategies/ParticleSwarmOptimization.java +++ b/src/eva2/server/go/strategies/ParticleSwarmOptimization.java @@ -26,151 +26,141 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Vector; - -/** - * This implements particle swarm optimization by Kennedy and Eberhardt. - * Works fine but is limited to real-valued genotypes and the original - * version ignored range constraints on the decision variables. I've - * implemented 'brakes' before an individual is updated it is checked - * whether the new individual would violate range constraints, if so - * the velocity vector is reduced. - * - * Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" - * in that order starting by 0. - * - * Created by IntelliJ IDEA. - * User: streiche - * Date: 28.10.2004 - * Time: 11:23:21 - * To change this template use File | Settings | File Templates. +/** + * This implements particle swarm optimization by Kennedy and Eberhardt. Works + * fine but is limited to real-valued genotypes and the original version ignored + * range constraints on the decision variables. I've implemented 'brakes' before + * an individual is updated it is checked whether the new individual would + * violate range constraints, if so the velocity vector is reduced. + * + * Possible topologies are: "Linear", "Grid", "Star", "Multi-Swarm", "Tree", + * "HPSO", "Random" in that order starting by 0. + * + * Created by IntelliJ IDEA. User: streiche Date: 28.10.2004 Time: 11:23:21 To + * change this template use File | Settings | File Templates. */ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Serializable, InterfaceAdditionalPopulationInformer { - /** - * Generated serial version uid. - */ - private static final long serialVersionUID = -149996122795669589L; - - protected Population m_Population = new Population(); - Object[] sortedPop = null; - protected AbstractEAIndividual m_BestIndividual = null; - protected InterfaceOptimizationProblem m_Problem = new F1Problem(); - protected boolean m_CheckRange = true; - protected boolean checkSpeedLimit = false; - protected boolean useAlternative = false; - protected PSOTopologyEnum topology = PSOTopologyEnum.grid; - /** - * Defines which version of PSO is applied, classical inertness or constriction (using chi) - */ - protected SelectedTag algType; - protected int m_TopologyRange = 2; - protected double m_InitialVelocity = 0.2; - protected double m_SpeedLimit = 0.1; - protected double m_Phi1 = 2.05; - protected double m_Phi2 = 2.05; - // for multi-swarm topology: radius of the swarm relative to the range - protected double m_swarmRadius = 0.2; - // for multi-swarm: maximum sub swarm size. zero means unlimited - protected int maxSubSwarmSize = 0; - protected int minSubSwarmSize = 2; - protected int treeStruct = 1; - protected boolean wrapTopology = true; + /** + * Generated serial version uid. + */ + private static final long serialVersionUID = -149996122795669589L; + protected Population m_Population = new Population(); + Object[] sortedPop = null; + protected AbstractEAIndividual m_BestIndividual = null; + protected InterfaceOptimizationProblem m_Problem = new F1Problem(); + protected boolean m_CheckRange = true; + protected boolean checkSpeedLimit = false; + protected boolean useAlternative = false; + protected PSOTopologyEnum topology = PSOTopologyEnum.grid; + /** + * Defines which version of PSO is applied, classical inertness or + * constriction (using chi) + */ + protected SelectedTag algType; + protected int m_TopologyRange = 2; + protected double m_InitialVelocity = 0.2; + protected double m_SpeedLimit = 0.1; + protected double m_Phi1 = 2.05; + protected double m_Phi2 = 2.05; + // for multi-swarm topology: radius of the swarm relative to the range + protected double m_swarmRadius = 0.2; + // for multi-swarm: maximum sub swarm size. zero means unlimited + protected int maxSubSwarmSize = 0; + protected int minSubSwarmSize = 2; + protected int treeStruct = 1; + protected boolean wrapTopology = true; // protected boolean doLocalSearch = false; // protected int localSearchGens=100; // protected int lsStepsPerInd=200; - protected int treeLevels, treeOrphans, treeLastFullLevelNodeCnt; - protected int dmsRegroupInterval = 10; - private transient Vector dmsLinks = null; - protected ParameterControlManager paramControl = new ParameterControlManager(); - - /** - * InertnessOrChi may contain the inertness or chi parameter depending on algoType - */ - protected double m_InertnessOrChi = 0.73; - protected double m_ReduceSpeed = 0.8; - private double reduceSpeedOnConstViolation = 0.5; - public static final int defaultType = 0; - public static final int resetType = 99; - transient final static String partTypeKey = "ParticleType"; - public transient final static String partBestPosKey = "BestPosition"; - transient final static String partBestFitKey = "BestFitness"; - public transient final static String partVelKey = "Velocity"; - transient final static String multiSwTypeKey="MultiSwarmType"; - transient final static String multiSwSizeKey="MultiSwarmSize"; - transient final static String indexKey="particleIndex"; - transient final static String sortedIndexKey="sortedParticleIndex"; - transient final static String dmsGroupIndexKey="dmsGroupIndex"; - - protected String m_Identifier = ""; - transient private InterfacePopulationChangedEventListener m_Listener; - transient private TopoPlot topoPlot = null; - - /// sleep time so that visual plot can be followed easier - protected int sleepTime = 0; - - // for tracing the average velocity - transient private double[] tracedVelocity = null; - // parameter for exponential moving average - private int emaPeriods = 0; - - // for debugging only - transient private static boolean TRACE = false; - transient protected boolean m_Show = false; - transient protected eva2.gui.Plot m_Plot; - - private boolean externalInitialPop = false; - private static String lastSuccessKey = "successfulUpdate"; + protected int treeLevels, treeOrphans, treeLastFullLevelNodeCnt; + protected int dmsRegroupInterval = 10; + private transient Vector dmsLinks = null; + protected ParameterControlManager paramControl = new ParameterControlManager(); + /** + * InertnessOrChi may contain the inertness or chi parameter depending on + * algoType + */ + protected double m_InertnessOrChi = 0.73; + protected double m_ReduceSpeed = 0.8; + private double reduceSpeedOnConstViolation = 0.5; + public static final int defaultType = 0; + public static final int resetType = 99; + transient final static String partTypeKey = "ParticleType"; + public transient final static String partBestPosKey = "BestPosition"; + transient final static String partBestFitKey = "BestFitness"; + public transient final static String partVelKey = "Velocity"; + transient final static String multiSwTypeKey = "MultiSwarmType"; + transient final static String multiSwSizeKey = "MultiSwarmSize"; + transient final static String indexKey = "particleIndex"; + transient final static String sortedIndexKey = "sortedParticleIndex"; + transient final static String dmsGroupIndexKey = "dmsGroupIndex"; + protected String m_Identifier = ""; + transient private InterfacePopulationChangedEventListener m_Listener; + transient private TopoPlot topoPlot = null; + /// sleep time so that visual plot can be followed easier + protected int sleepTime = 0; + // for tracing the average velocity + transient private double[] tracedVelocity = null; + // parameter for exponential moving average + private int emaPeriods = 0; + // for debugging only + transient private static boolean TRACE = false; + transient protected boolean m_Show = false; + transient protected eva2.gui.Plot m_Plot; + private boolean externalInitialPop = false; + private static String lastSuccessKey = "successfulUpdate"; // private double lsCandidateRatio=0.25; - - public ParticleSwarmOptimization() { + public ParticleSwarmOptimization() { // this.m_Topology = new SelectedTag( "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" ); // m_Topology.setSelectedTag(1); - topology = PSOTopologyEnum.grid; - algType = new SelectedTag("Inertness", "Constriction"); - algType.setSelectedTag(1); + topology = PSOTopologyEnum.grid; + algType = new SelectedTag("Inertness", "Constriction"); + algType.setSelectedTag(1); - setConstriction(getPhi1(), getPhi2()); - hideHideable(); - } + setConstriction(getPhi1(), getPhi2()); + hideHideable(); + } - public ParticleSwarmOptimization(ParticleSwarmOptimization a) { - topology=a.topology; + public ParticleSwarmOptimization(ParticleSwarmOptimization a) { + topology = a.topology; // if (a.m_Topology != null) // this.m_Topology = (SelectedTag)a.m_Topology.clone(); - if (a.algType != null) - this.algType = (SelectedTag)a.algType.clone(); - this.m_Population = (Population)a.m_Population.clone(); - this.m_Problem = a.m_Problem; - this.m_Identifier = a.m_Identifier; - this.m_InitialVelocity = a.m_InitialVelocity; - this.m_SpeedLimit = a.m_SpeedLimit; - this.m_Phi1 = a.m_Phi1; - this.m_Phi2 = a.m_Phi2; - this.m_InertnessOrChi = a.m_InertnessOrChi; - this.m_TopologyRange = a.m_TopologyRange; - this.paramControl = (ParameterControlManager) a.paramControl.clone(); - //this.setCheckSpeedLimit(a.isCheckSpeedLimit()); - } + if (a.algType != null) { + this.algType = (SelectedTag) a.algType.clone(); + } + this.m_Population = (Population) a.m_Population.clone(); + this.m_Problem = a.m_Problem; + this.m_Identifier = a.m_Identifier; + this.m_InitialVelocity = a.m_InitialVelocity; + this.m_SpeedLimit = a.m_SpeedLimit; + this.m_Phi1 = a.m_Phi1; + this.m_Phi2 = a.m_Phi2; + this.m_InertnessOrChi = a.m_InertnessOrChi; + this.m_TopologyRange = a.m_TopologyRange; + this.paramControl = (ParameterControlManager) a.paramControl.clone(); + //this.setCheckSpeedLimit(a.isCheckSpeedLimit()); + } + + /** + * Constructor for most common parameters with constriction based approach. + * + * @param popSize swarm size + * @param p1 the value for phi1 + * @param p2 the value for phi1 + * @param topo type of the neighbourhood topology + * @param topoRange range of the neighbourhood topology + */ + public ParticleSwarmOptimization(int popSize, double p1, double p2, PSOTopologyEnum topo, int topoRange) { + this(); + algType.setSelectedTag(1); // set to constriction + m_Population = new Population(popSize); + setPhiValues(p1, p2); + m_TopologyRange = topoRange; + topology = topo; + } - /** - * Constructor for most common parameters with constriction based approach. - * - * @param popSize swarm size - * @param p1 the value for phi1 - * @param p2 the value for phi1 - * @param topo type of the neighbourhood topology - * @param topoRange range of the neighbourhood topology - */ - public ParticleSwarmOptimization(int popSize, double p1, double p2, PSOTopologyEnum topo, int topoRange) { - this(); - algType.setSelectedTag(1); // set to constriction - m_Population = new Population(popSize); - setPhiValues(p1, p2); - m_TopologyRange=topoRange; - topology=topo; - } - // /** // * Constructor for most common parameters with constriction based approach and local search. // * @@ -190,447 +180,511 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // lsStepsPerInd=stepsPerInd; // lsCandidateRatio = candidateRatio; // } - - public Object clone() { - return (Object) new ParticleSwarmOptimization(this); - } + public Object clone() { + return (Object) new ParticleSwarmOptimization(this); + } - /** - * 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. - */ - public void hideHideable() { - setCheckSpeedLimit(checkSpeedLimit); - setTopology(getTopology()); - } + /** + * 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. + */ + public void hideHideable() { + setCheckSpeedLimit(checkSpeedLimit); + setTopology(getTopology()); + } - public void init() { - if (m_Plot!= null) { + public void init() { + if (m_Plot != null) { // m_Plot.dispose(); - m_Plot = null; - } - if (topoPlot!= null) { + m_Plot = null; + } + if (topoPlot != null) { // topoPlot.dispose(); - topoPlot = null; - } - tracedVelocity = null; - if (!externalInitialPop) this.m_Problem.initPopulation(this.m_Population); - // evaluation needs to be done here now, as its omitted if reset is false - initDefaults(this.m_Population); - this.evaluatePopulation(this.m_Population); - if (m_BestIndividual == null) m_BestIndividual = m_Population.getBestEAIndividual(); - initByPopulation(null, false); - externalInitialPop = false; - } - - /** - * Set the initial random velocity vector. - * - * @param indy the individual to work on - * @param initialV initial velocity relative to the range - */ - public static void initIndividualDefaults(AbstractEAIndividual indy, double initialV) { - double[] writeData; - // init velocity - writeData=Mathematics.randomVector(((InterfaceDataTypeDouble)indy).getDoubleData().length, 1); - - //sum = Math.sqrt(sum); - double relSpeed = Mathematics.getRelativeLength(writeData, ((InterfaceDataTypeDouble)indy).getDoubleRange()); - for (int j = 0; j < writeData.length; j++) { - writeData[j] = (writeData[j]/relSpeed)*initialV; - } - indy.putData(partTypeKey, defaultType); - indy.putData(partVelKey, writeData); - } - - /** - * Set current position and fitness as best personal position and fitness. - * - * @param indy the individual to work on - */ - protected static void initIndividualMemory(AbstractEAIndividual indy) { - // init best fitness - double[] tmpD = indy.getFitness(); - double[] writeData = new double[tmpD.length]; - System.arraycopy(tmpD, 0, writeData, 0, tmpD.length); - indy.putData(partBestFitKey, writeData); - // init best position - tmpD = ((InterfaceDataTypeDouble)indy).getDoubleData(); - writeData = new double[tmpD.length]; - System.arraycopy(tmpD, 0, writeData, 0, tmpD.length); - indy.putData(partBestPosKey, writeData); - } - - /** - * Update the exponential moving average of the population velocity with the current population. - * - * @param population - */ - protected void traceEMA(Population population) { - if (population.get(0) instanceof InterfaceDataTypeDouble) { - double[] curAvVelAndSpeed; - if (population.getGeneration() == 0) return; - - curAvVelAndSpeed = getPopulationVelSpeed(population, 3, partVelKey, partTypeKey, defaultType); - double[][] range = ((InterfaceDataTypeDouble)population.get(0)).getDoubleRange(); - if (tracedVelocity == null) { - tracedVelocity = new double[((InterfaceDataTypeDouble)population.get(0)).getDoubleData().length]; - for (int i=0; i 0); - boolean calcAbsSpeedAverage = ((calcModeSwitch & 2) > 0); - if ((calcModeSwitch & 3) == 0) System.err.println("Error, switch must be 1, 2 or 3 (getPopulationVelSpeed)"); - - double[] velocity = (double[]) indy.getData(velocityKey); - if (velocity != null) { - if (calcVectVelocity) retSize+=velocity.length; // entries for cumulative velocity - if (calcAbsSpeedAverage) retSize++; // one entry for average absolute speed - // return length of the array depends on what should be calculated - ret = new double[retSize]; - - double[] cumulVeloc = new double[velocity.length]; - double avSpeed = 0.; - - for (int i=0; i 0) { - traceEMA(population); - } + double[] ret; + double[][] range = ((InterfaceDataTypeDouble) indy).getDoubleRange(); + int retSize = 0; + ///// warning, this method uses dark magic + + boolean calcVectVelocity = ((calcModeSwitch & 1) > 0); + boolean calcAbsSpeedAverage = ((calcModeSwitch & 2) > 0); + if ((calcModeSwitch & 3) == 0) { + System.err.println("Error, switch must be 1, 2 or 3 (getPopulationVelSpeed)"); + } + + double[] velocity = (double[]) indy.getData(velocityKey); + if (velocity != null) { + if (calcVectVelocity) { + retSize += velocity.length; // entries for cumulative velocity + } + if (calcAbsSpeedAverage) { + retSize++; // one entry for average absolute speed + } // return length of the array depends on what should be calculated + ret = new double[retSize]; + + double[] cumulVeloc = new double[velocity.length]; + double avSpeed = 0.; + + for (int i = 0; i < cumulVeloc.length; i++) { + cumulVeloc[i] = 0.; + } + int indCnt = 0; + + for (int i = 0; i < pop.size(); i++) { + indy = (AbstractEAIndividual) pop.get(i); + + if (indy.hasData(velocityKey)) { + velocity = (double[]) (indy.getData(velocityKey)); + if (velocity != null) { + if ((typeString == null) || (indy.getData(typeString).equals(requiredType))) { + //if (particleHasSpeed(indy)) { + indCnt++; + if (calcVectVelocity) { + for (int j = 0; j < cumulVeloc.length; j++) { + cumulVeloc[j] += velocity[j]; + } + } + if (calcAbsSpeedAverage) { + avSpeed += Mathematics.getRelativeLength(velocity, range); + } + } + } else { + System.err.println("Error: Indy without velocity!! (getPopulationVelSpeed)"); + } + } + } + if (calcVectVelocity) { + for (int j = 0; j < cumulVeloc.length; j++) { + ret[j] = cumulVeloc[j] / ((double) indCnt); + } + } + if (calcAbsSpeedAverage) { + avSpeed /= ((double) indCnt); + ret[ret.length - 1] = avSpeed; + } + return ret; + } else { + System.err.println("warning, no speed in particle! (getPopulationVelocity)"); + return null; + } + //for (int j=0; j 0) { + traceEMA(population); + } // AbstractEAIndividual indy = population.getBestEAIndividual(); - //System.out.println("best ind at " + indy.getStringRepresentation() + " , fit is " + indy.getFitness(0)); - //try { Thread.sleep(10); } catch(Exception e) {} - } + //System.out.println("best ind at " + indy.getStringRepresentation() + " , fit is " + indy.getFitness(0)); + //try { Thread.sleep(10); } catch(Exception e) {} + } - public static void dumpPop(String prefix, Population pop) { - if (prefix!=null) System.out.println(prefix); - for (int i=0; i= tmpFit[0]) { // now multi-obj. - if (AbstractEAIndividual.isDominatingFitness(neighbourFit, attractorFit)) { // if the remembered fitness dominates the given one, overwrite the given one - // replace best fitness and position with current best - System.arraycopy(neighbourFit, 0, attractorFit, 0, neighbourFit.length); - System.arraycopy(neighbourPos, 0, attractorPos, 0, neighbourPos.length); - } - } + if (AbstractEAIndividual.isDominatingFitness(neighbourFit, attractorFit)) { // if the remembered fitness dominates the given one, overwrite the given one + // replace best fitness and position with current best + System.arraycopy(neighbourFit, 0, attractorFit, 0, neighbourFit.length); + System.arraycopy(neighbourPos, 0, attractorPos, 0, neighbourPos.length); + } + } - protected void resetIndividual(AbstractEAIndividual indy) { - resetIndividual(indy, m_InitialVelocity); - plotIndy(((InterfaceDataTypeDouble)indy).getDoubleData(), null, (Integer)indy.getData(indexKey)); - } - - public static void resetIndividual(AbstractEAIndividual indy, double initialV) { - if (indy instanceof InterfaceDataTypeDouble) { - indy.setParents(null); - indy.defaultInit(null); - indy.putData(partTypeKey, defaultType); // turn into default type - initIndividualDefaults(indy, initialV); - initIndividualMemory(indy); - } else System.err.println("error, double valued individuals required for PSO"); - } - - /** This method will update a given individual - * according to the PSO method - * @param index The individual to update. - * @param pop The current population. - * @param best The best individual found so far. - */ - protected void updateIndividual(int index, AbstractEAIndividual indy, Population pop) { - if (indy instanceof InterfaceDataTypeDouble) { - int type=(Integer)indy.getData(partTypeKey); - switch (type) { - case resetType: - resetIndividual(indy); - break; - case defaultType: - defaultIndividualUpdate(index, indy, pop); - break; - default: System.err.println("particle type " + type + " unknown!"); break; - } - } else { - throw new RuntimeException("Could not perform PSO update, because individual is not instance of InterfaceESIndividual!"); - } - } - - protected void defaultIndividualUpdate(int index, AbstractEAIndividual indy, Population pop) { - InterfaceDataTypeDouble endy = (InterfaceDataTypeDouble) indy; - - indy.putData(partTypeKey, defaultType); - // default update - double[] personalBestPos = (double[]) indy.getData(partBestPosKey); - double[] velocity = (double[]) indy.getData(partVelKey); - double[] curPosition = endy.getDoubleData(); - double[][] range = endy.getDoubleRange(); + protected void resetIndividual(AbstractEAIndividual indy) { + resetIndividual(indy, m_InitialVelocity); + plotIndy(((InterfaceDataTypeDouble) indy).getDoubleData(), null, (Integer) indy.getData(indexKey)); + } - // search for the local best position - double[] neighbourBestPos = findNeighbourhoodOptimum(index, pop); + public static void resetIndividual(AbstractEAIndividual indy, double initialV) { + if (indy instanceof InterfaceDataTypeDouble) { + indy.setParents(null); + indy.defaultInit(null); + indy.putData(partTypeKey, defaultType); // turn into default type + initIndividualDefaults(indy, initialV); + initIndividualMemory(indy); + } else { + System.err.println("error, double valued individuals required for PSO"); + } + } - // now update the velocity - double[] curVelocity = updateVelocity(index, velocity, personalBestPos, curPosition, neighbourBestPos, range); + /** + * This method will update a given individual according to the PSO method + * + * @param index The individual to update. + * @param pop The current population. + * @param best The best individual found so far. + */ + protected void updateIndividual(int index, AbstractEAIndividual indy, Population pop) { + if (indy instanceof InterfaceDataTypeDouble) { + int type = (Integer) indy.getData(partTypeKey); + switch (type) { + case resetType: + resetIndividual(indy); + break; + case defaultType: + defaultIndividualUpdate(index, indy, pop); + break; + default: + System.err.println("particle type " + type + " unknown!"); + break; + } + } else { + throw new RuntimeException("Could not perform PSO update, because individual is not instance of InterfaceESIndividual!"); + } + } - // check the speed limit - if (checkSpeedLimit) enforceSpeedLimit(curVelocity, range, getSpeedLimit(index)); + protected void defaultIndividualUpdate(int index, AbstractEAIndividual indy, Population pop) { + InterfaceDataTypeDouble endy = (InterfaceDataTypeDouble) indy; - // enforce range constraints if necessary - if (m_CheckRange) ensureConstraints(curPosition, curVelocity, range); + indy.putData(partTypeKey, defaultType); + // default update + double[] personalBestPos = (double[]) indy.getData(partBestPosKey); + double[] velocity = (double[]) indy.getData(partVelKey); + double[] curPosition = endy.getDoubleData(); + double[][] range = endy.getDoubleRange(); - plotIndy(curPosition, curVelocity, (Integer)indy.getData(indexKey)); - // finally update the position - updatePosition(indy, curVelocity, curPosition, range); + // search for the local best position + double[] neighbourBestPos = findNeighbourhoodOptimum(index, pop); - resetFitness(indy); - } + // now update the velocity + double[] curVelocity = updateVelocity(index, velocity, personalBestPos, curPosition, neighbourBestPos, range); - protected void plotIndy(double[] curPosition, double[] curVelocity, int index) { - if (this.m_Show) { - if (curVelocity == null) { - this.m_Plot.setUnconnectedPoint(curPosition[0], curPosition[1], index); - } else { - this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index); - this.m_Plot.setConnectedPoint(curPosition[0] + curVelocity[0], curPosition[1] + curVelocity[1], index); - } + // check the speed limit + if (checkSpeedLimit) { + enforceSpeedLimit(curVelocity, range, getSpeedLimit(index)); + } + + // enforce range constraints if necessary + if (m_CheckRange) { + ensureConstraints(curPosition, curVelocity, range); + } + + plotIndy(curPosition, curVelocity, (Integer) indy.getData(indexKey)); + // finally update the position + updatePosition(indy, curVelocity, curPosition, range); + + resetFitness(indy); + } + + protected void plotIndy(double[] curPosition, double[] curVelocity, int index) { + if (this.m_Show) { + if (curVelocity == null) { + this.m_Plot.setUnconnectedPoint(curPosition[0], curPosition[1], index); + } else { + this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index); + this.m_Plot.setConnectedPoint(curPosition[0] + curVelocity[0], curPosition[1] + curVelocity[1], index); + } // m_Plot = null; // show(); @@ -639,7 +693,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // m_Plot.setUnconnectedPoint(-10, -10, 0); // m_Plot.setUnconnectedPoint(10, 10, 0); // } - + // if (index != 0) return; // double[] bestPosition = (double[])m_BestIndividual.getData(partBestPosKey); // double[] localBestPos = findNeighbourhoodOptimum(index, m_Population); @@ -650,77 +704,81 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index+3); // this.m_Plot.setConnectedPoint(localBestPos[0], localBestPos[1], index+3); - // this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index+1); - // this.m_Plot.setConnectedPoint(localBestPosition[0], localBestPosition[1], index+1); - // this.m_Plot.setConnectedPoint(curPosition[0], curPosition[1], index+1); - // this.m_Plot.setConnectedPoint(bestPosition[0], bestPosition[1], index+1); - // this.m_Plot.setUnconnectedPoint(curPosition[0], curPosition[1], 100*index+1); - } - } - - /** - * Loop the population and update each individual props if indicated by isIndividualToUpdate. - * - * @param pop the population to work on - */ - protected void updateSwarmMemory(Population pop) { - for (int i=0; i successes = new ArrayList(); - for (int i = 0; i < this.m_Population.size(); i++) { - double[] succVel = (double[])m_Population.getEAIndividual(i).getData(lastSuccessKey); - if (succVel!=null) successes.add(new Integer(i)); - } - if (successes.size()>0) { - int i = successes.get(RNG.randomInt(successes.size())); - return (double[])m_Population.getEAIndividual(i).getData(lastSuccessKey); - } else return null; - } - } + if (successfulVel != null) { + Mathematics.vvAdd(accel, successfulVel, accel); + Mathematics.svMult(0.5, accel, accel); + } + return accel; + } + + private double[] getSuccessfulVel(int index) { + if (true) { + return (double[]) m_Population.getEAIndividual(index).getData(lastSuccessKey); + } else { // random one + ArrayList successes = new ArrayList(); + for (int i = 0; i < this.m_Population.size(); i++) { + double[] succVel = (double[]) m_Population.getEAIndividual(i).getData(lastSuccessKey); + if (succVel != null) { + successes.add(new Integer(i)); + } + } + if (successes.size() > 0) { + int i = successes.get(RNG.randomInt(successes.size())); + return (double[]) m_Population.getEAIndividual(i).getData(lastSuccessKey); + } else { + return null; + } + } + } // protected double[] getAccelerationAlternative(double[] personalBestPos, double[] neighbourBestPos, double[] curPosition, double[][] range) { // double[] accel = new double[curPosition.length]; @@ -865,7 +930,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // return accel; // } // } - // public static void main(String[] args) { // ParticleSwarmOptimization pso = new ParticleSwarmOptimization(); // GVector tmp, vec = new GVector(5); @@ -890,385 +954,420 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // //vecSum.normalize(); // //System.out.println(vec.toString() + " -> " + vecSum.toString()); // } - - /** - * Return a random vector after a gaussian distribution oriented along dir, meaning that - * variance is len(dir) along dir and len(dir)/scale in any other direction. - * If dir is a null-vector, having neither direction nor length, a null vector is returned. - * - * @param dir - * @return - */ - protected Matrix getOrientedGaussianRandomVectorB(Matrix dir, double scale) { - double len = dir.norm2(); - int dim = dir.getRowDimension(); + /** + * Return a random vector after a gaussian distribution oriented along dir, + * meaning that variance is len(dir) along dir and len(dir)/scale in any + * other direction. If dir is a null-vector, having neither direction nor + * length, a null vector is returned. + * + * @param dir + * @return + */ + protected Matrix getOrientedGaussianRandomVectorB(Matrix dir, double scale) { + double len = dir.norm2(); + int dim = dir.getRowDimension(); - Matrix resVec = new Matrix(dim, 1); - Matrix randVec = new Matrix(dim, 1); - - if (len > 0) { - // initialize random vector + Matrix resVec = new Matrix(dim, 1); + Matrix randVec = new Matrix(dim, 1); + + if (len > 0) { + // initialize random vector // randVec.set(0, 0, len/2.+RNG.gaussianDouble(len/2)); // for (int i=1; i max) return max; - else return val; - } + randVec.set(0, 0, project(0, len, len / 2 + RNG.gaussianDouble(len / 2))); + for (int i = 1; i < dim; i++) { + randVec.set(i, 0, project(-len / 2, len / 2, RNG.gaussianDouble(len / (scale * 2)))); + } + Matrix rotation = Mathematics.getRotationMatrix(dir); + rotation = rotation.transpose(); + //printMatrix(rotation); + resVec = rotation.times(randVec); + } + return resVec; + } - protected void printMatrix(Matrix M) { - for (int i=0; i= 0) && (tmpIndex < pop.size())) { - this.compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual)pop.get(tmpIndex), useHistoric); - } - } - break; - case grid: - // grid - int corner = 1+(int)Math.sqrt(pop.size()); - for (int x = -this.m_TopologyRange; x <= this.m_TopologyRange; x++) { - for (int y = -this.m_TopologyRange; y <= this.m_TopologyRange; y++) { - tmpIndex = index + x + (y*corner); - if (wrapTopology) tmpIndex=(tmpIndex + pop.size())% pop.size(); // wrap the grid toroidal - if ((x != index) && (tmpIndex >= 0) && (tmpIndex < pop.size())) { - this.compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual)pop.get(tmpIndex), useHistoric); - } - } - } - break; - case star: - // star: only compare to the absolutely best - this.compareAndSetAttractor(localBestFitness, localBestPosition, bestIndy, useHistoric); - break; - case multiSwarm: - // self-organised multi-swarms - AbstractEAIndividual leader = (AbstractEAIndividual)indy.getData(multiSwTypeKey); - if (leader != null) { // refer to position of leader, this may be the individual itself - if ((leader == indy) && ((Integer)indy.getData(multiSwSizeKey) < minSubSwarmSize)) { - // swarm too small - this.compareAndSetAttractor(localBestFitness, localBestPosition, bestIndy, useHistoric); - //System.out.println("swarm too small.. using global attractor"); - } else { + public static double project(double min, double max, double val) { + if (val < min) { + return min; + } else if (val > max) { + return max; + } else { + return val; + } + } + + protected void printMatrix(Matrix M) { + for (int i = 0; i < M.getRowDimension(); i++) { + for (int j = 0; j < M.getColumnDimension(); j++) { + System.out.print(" " + M.get(i, j)); + } + System.out.println(""); + } + } + + /** + * In the topology range for the given index, find the best stored + * individual and return its position. + * + * @param index index of the individual for which to check + * @param pop the current swarm + * @param best the currently best individual + * @return a copy of the position of the best remembered individual in the + * neigbourhood + */ + protected double[] findNeighbourhoodOptimum(int index, Population pop) { + double[] localBestPosition = null; + double[] localBestFitness = null; + int tmpIndex; + AbstractEAIndividual bestIndy, indy = pop.getEAIndividual(index); + boolean useHistoric = true; + int sortedIndex = -1; + int k; + + localBestFitness = ((double[]) (indy).getData(partBestFitKey)).clone(); + localBestPosition = ((double[]) (indy).getData(partBestPosKey)).clone(); + if (useHistoric) { + bestIndy = m_BestIndividual; + } else { + bestIndy = pop.getBestEAIndividual(); + } + + switch (topology) { + case linear: + // linear + for (int x = -this.m_TopologyRange; x <= this.m_TopologyRange; x++) { + if (wrapTopology) { + tmpIndex = (index + x + pop.size()) % pop.size(); + } else { + tmpIndex = index + x; + } + + if ((x != 0) && (tmpIndex >= 0) && (tmpIndex < pop.size())) { + this.compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual) pop.get(tmpIndex), useHistoric); + } + } + break; + case grid: + // grid + int corner = 1 + (int) Math.sqrt(pop.size()); + for (int x = -this.m_TopologyRange; x <= this.m_TopologyRange; x++) { + for (int y = -this.m_TopologyRange; y <= this.m_TopologyRange; y++) { + tmpIndex = index + x + (y * corner); + if (wrapTopology) { + tmpIndex = (tmpIndex + pop.size()) % pop.size(); // wrap the grid toroidal + } + if ((x != index) && (tmpIndex >= 0) && (tmpIndex < pop.size())) { + this.compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual) pop.get(tmpIndex), useHistoric); + } + } + } + break; + case star: + // star: only compare to the absolutely best + this.compareAndSetAttractor(localBestFitness, localBestPosition, bestIndy, useHistoric); + break; + case multiSwarm: + // self-organised multi-swarms + AbstractEAIndividual leader = (AbstractEAIndividual) indy.getData(multiSwTypeKey); + if (leader != null) { // refer to position of leader, this may be the individual itself + if ((leader == indy) && ((Integer) indy.getData(multiSwSizeKey) < minSubSwarmSize)) { + // swarm too small + this.compareAndSetAttractor(localBestFitness, localBestPosition, bestIndy, useHistoric); + //System.out.println("swarm too small.. using global attractor"); + } else { // if (!Arrays.equals(((InterfaceESIndividual)leader).getDGenotype(), ((InterfaceESIndividual)bestIndy).getDGenotype())) { // System.out.println("leader is different from best"); // } - this.compareAndSetAttractor(localBestFitness, localBestPosition, leader, false); - } - } else { - // TODO handle this? - System.err.println("no leader present!"); - } - break; - case tree: // Sorted Tree - sortedIndex = (Integer)((AbstractEAIndividual)sortedPop[index]).getData(sortedIndexKey); + this.compareAndSetAttractor(localBestFitness, localBestPosition, leader, false); + } + } else { + // TODO handle this? + System.err.println("no leader present!"); + } + break; + case tree: // Sorted Tree + sortedIndex = (Integer) ((AbstractEAIndividual) sortedPop[index]).getData(sortedIndexKey); - if (sortedIndex>0) { // its found and its not the root. root has no parent to check for - k = getParentIndex(m_TopologyRange, sortedIndex, pop.size()); - compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual)sortedPop[k], useHistoric); - } - if (treeStruct == 1) { // loop all children - if (isComplete(sortedIndex, pop.size())) { // the node has full degree - k = m_TopologyRange*sortedIndex+1; // this is the offset of the nodes children - for (int i=0; i 0) { - k = indexOfFirstOrphan(sortedIndex, pop.size()); - for (int i=0; i 0) { // its found and its not the root. root has no parent to check for + k = getParentIndex(m_TopologyRange, sortedIndex, pop.size()); + compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual) sortedPop[k], useHistoric); + } + if (treeStruct == 1) { // loop all children + if (isComplete(sortedIndex, pop.size())) { // the node has full degree + k = m_TopologyRange * sortedIndex + 1; // this is the offset of the nodes children + for (int i = 0; i < m_TopologyRange; i++) { + compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual) sortedPop[k + i], useHistoric); + } + } else if (isIncomplete(sortedIndex, pop.size())) { // the node does not have full degree but might have orphans + int numOrphs = numOrphans(sortedIndex, pop.size()); + if (numOrphs > 0) { + k = indexOfFirstOrphan(sortedIndex, pop.size()); + for (int i = 0; i < numOrphs; i++) { + compareAndSetAttractor(localBestFitness, localBestPosition, (AbstractEAIndividual) sortedPop[k], useHistoric); + k += treeLastFullLevelNodeCnt; // hop to next (possible) orphan index + } + } + } + // this was the binary variant // k = (2*sortedIndex+1); // if (k < pop.size()) { // compareAndSet(localBestFitness, localBestPosition, (AbstractEAIndividual)sortedPop[k], useHistoric); // k++; // if (k < pop.size()) compareAndSet(localBestFitness, localBestPosition, (AbstractEAIndividual)sortedPop[k], useHistoric); // } - } - break; - case hpso: // Hierarchical PSO - if (index>=0) { - k = getParentIndex(m_TopologyRange, index, pop.size()); + } + break; + case hpso: // Hierarchical PSO + if (index >= 0) { + k = getParentIndex(m_TopologyRange, index, pop.size()); // compareAndSet(localBestFitness, localBestPosition, (AbstractEAIndividual)pop.get(k), useHistoric); - indy = (AbstractEAIndividual)pop.get(k); - System.arraycopy((double[])indy.getData(partBestFitKey), 0, localBestFitness, 0, localBestFitness.length); - System.arraycopy((double[])indy.getData(partBestPosKey), 0, localBestPosition, 0, localBestPosition.length); + indy = (AbstractEAIndividual) pop.get(k); + System.arraycopy((double[]) indy.getData(partBestFitKey), 0, localBestFitness, 0, localBestFitness.length); + System.arraycopy((double[]) indy.getData(partBestPosKey), 0, localBestPosition, 0, localBestPosition.length); - } - break; - case random: // m_TopologyRange random informants, may be the same several times - for (int i=0; i= popSize - treeOrphans); - } - - protected boolean isComplete(int index, int popSize) { - return (index < popSize-treeOrphans-treeLastFullLevelNodeCnt); - } - - protected boolean isIncomplete(int index, int popSize) { - return ((index < popSize-treeOrphans) && (index >= popSize-treeOrphans-treeLastFullLevelNodeCnt)); - } - - /** - * Calculate the number of child orphans for tree nodes in the last internal layer (which is not complete, - * in the sense the nodes do not have full degree). Returns -1 if the indexed node is an orphan itself, - * or it is within a complete layer or if the index is out of range. - * - * @param index - * @param popSize - * @return - */ - protected int numOrphans(int index, int popSize) { - int k; - if (isIncomplete(index, popSize)) { - k = treeOrphans / treeLastFullLevelNodeCnt; - // if the index lies within orphans modulo lastFullCnt starting from lastFullLevel offset, there is one more child node - if ((index - (popSize-treeOrphans-treeLastFullLevelNodeCnt)) >= (treeOrphans % treeLastFullLevelNodeCnt)) return k; - else return k+1; - } else return -1; - } - - protected int indexOfFirstOrphan(int index, int popSize) { - if (isIncomplete(index, popSize)) { - int k = popSize - treeOrphans + (index - (popSize - treeOrphans - treeLastFullLevelNodeCnt)); - return k; - } else return -1; - } - - /** - * Update the given individuals position with given speed and position, maybe perform checkBounds. - * Remember to reset the fitness and constraint violation of the individual. - * - * @param indy - * @param curVelocity - * @param curPosition - * @param range - */ - protected void updatePosition(AbstractEAIndividual indy, double[] curVelocity, double[] curPosition, double[][] range) { - double[] newPosition = new double[curPosition.length]; + } + break; + case random: // m_TopologyRange random informants, may be the same several times + for (int i = 0; i < m_TopologyRange; i++) { + // select random informant + indy = (AbstractEAIndividual) pop.get(RNG.randomInt(0, pop.size() - 1)); + // set local values + compareAndSetAttractor(localBestFitness, localBestPosition, indy, useHistoric); + } + break; + case dms: + int groupIndex = (Integer) pop.getEAIndividual(index).getData(dmsGroupIndexKey); + int[] groupLinks = dmsLinks.get(groupIndex); + for (int i = 0; i < groupLinks.length; i++) { + if (groupLinks[i] != index) { + // select informant + indy = pop.getEAIndividual(groupLinks[i]); + // set local values + compareAndSetAttractor(localBestFitness, localBestPosition, indy, useHistoric); + } + } + break; + } + return localBestPosition; + } - for (int i = 0; i < curPosition.length; i++) { - newPosition[i] = curPosition[i] + curVelocity[i]; - } - if (m_CheckRange && isOutOfRange(newPosition, range)) { - System.err.println("error, individual violates constraints!"); - } + /** + * Calculate a the parent index to a given index in a tree structure. The + * tree is complete except the last level, which is filled by assigning each + * parent of the last full level an orphan from left to right, so that no + * two parents differ in degree by more than one. + * + * @param branch + * @param index + * @param popSize + * @return + */ + protected int getParentIndex(int branch, int index, int popSize) { + int k; + if (isOrphan(index, popSize)) { + k = popSize - treeOrphans - treeLastFullLevelNodeCnt; + k += ((index - popSize + treeOrphans) % treeLastFullLevelNodeCnt); // index of the parent + } else { + k = (index - 1) / branch; + } + return k; + } - // finally set the new position and the current velocity - if (indy instanceof InterfaceDataTypeDouble) ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(newPosition); - else { - ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(newPosition); // WARNING, this does a checkBounds in any case! - if (!m_CheckRange) System.err.println("warning, checkbounds will be forced by InterfaceESIndividual!"); - } + protected boolean isOrphan(int index, int popSize) { + return (index >= popSize - treeOrphans); + } - indy.putData(partVelKey, curVelocity); + protected boolean isComplete(int index, int popSize) { + return (index < popSize - treeOrphans - treeLastFullLevelNodeCnt); + } + + protected boolean isIncomplete(int index, int popSize) { + return ((index < popSize - treeOrphans) && (index >= popSize - treeOrphans - treeLastFullLevelNodeCnt)); + } + + /** + * Calculate the number of child orphans for tree nodes in the last internal + * layer (which is not complete, in the sense the nodes do not have full + * degree). Returns -1 if the indexed node is an orphan itself, or it is + * within a complete layer or if the index is out of range. + * + * @param index + * @param popSize + * @return + */ + protected int numOrphans(int index, int popSize) { + int k; + if (isIncomplete(index, popSize)) { + k = treeOrphans / treeLastFullLevelNodeCnt; + // if the index lies within orphans modulo lastFullCnt starting from lastFullLevel offset, there is one more child node + if ((index - (popSize - treeOrphans - treeLastFullLevelNodeCnt)) >= (treeOrphans % treeLastFullLevelNodeCnt)) { + return k; + } else { + return k + 1; + } + } else { + return -1; + } + } + + protected int indexOfFirstOrphan(int index, int popSize) { + if (isIncomplete(index, popSize)) { + int k = popSize - treeOrphans + (index - (popSize - treeOrphans - treeLastFullLevelNodeCnt)); + return k; + } else { + return -1; + } + } + + /** + * Update the given individuals position with given speed and position, + * maybe perform checkBounds. Remember to reset the fitness and constraint + * violation of the individual. + * + * @param indy + * @param curVelocity + * @param curPosition + * @param range + */ + protected void updatePosition(AbstractEAIndividual indy, double[] curVelocity, double[] curPosition, double[][] range) { + double[] newPosition = new double[curPosition.length]; + + for (int i = 0; i < curPosition.length; i++) { + newPosition[i] = curPosition[i] + curVelocity[i]; + } + if (m_CheckRange && isOutOfRange(newPosition, range)) { + System.err.println("error, individual violates constraints!"); + } + + // finally set the new position and the current velocity + if (indy instanceof InterfaceDataTypeDouble) { + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(newPosition); + } else { + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(newPosition); // WARNING, this does a checkBounds in any case! + if (!m_CheckRange) { + System.err.println("warning, checkbounds will be forced by InterfaceESIndividual!"); + } + } + + indy.putData(partVelKey, curVelocity); // ((InterfaceESIndividual) indy).SetDGenotype(newPosition); - } + } - /** - * Test a position for range violation efficiently. - * - * @param pos the position vector to test - * @param range the range array - * @return true, if pos violoates range, else false - */ - protected boolean isOutOfRange(double[] pos, double[][] range) { - boolean violatesRange = false; - for (int i = 0; i < pos.length; i++) { - if (!violatesRange) { - violatesRange = (pos[i] < range[i][0]) || (pos[i] > range[i][1]); - } else break; - } - return violatesRange; - } + /** + * Test a position for range violation efficiently. + * + * @param pos the position vector to test + * @param range the range array + * @return true, if pos violoates range, else false + */ + protected boolean isOutOfRange(double[] pos, double[][] range) { + boolean violatesRange = false; + for (int i = 0; i < pos.length; i++) { + if (!violatesRange) { + violatesRange = (pos[i] < range[i][0]) || (pos[i] > range[i][1]); + } else { + break; + } + } + return violatesRange; + } - /** - * Enforce the speed limit by repeatedly multiplying with the reduce-speed factor. - * Requires the range array because the speed is handled relative to the range. - * - * @param curVelocity the velocity vector to be modified - * @param range the range array - * @param speedLim the speed limit relative to the range - */ - protected void enforceSpeedLimit(double[] curVelocity, double[][] range, double speedLim) { - while (Mathematics.getRelativeLength(curVelocity, range) > speedLim) { - for (int i = 0; i < curVelocity.length; i++) { - curVelocity[i] *= this.m_ReduceSpeed; - } - } - } + /** + * Enforce the speed limit by repeatedly multiplying with the reduce-speed + * factor. Requires the range array because the speed is handled relative to + * the range. + * + * @param curVelocity the velocity vector to be modified + * @param range the range array + * @param speedLim the speed limit relative to the range + */ + protected void enforceSpeedLimit(double[] curVelocity, double[][] range, double speedLim) { + while (Mathematics.getRelativeLength(curVelocity, range) > speedLim) { + for (int i = 0; i < curVelocity.length; i++) { + curVelocity[i] *= this.m_ReduceSpeed; + } + } + } - /** - * Makes sure that the future position (after adding velocity to pos) remains inside the - * range array. Therefore, the velocity may be repeatedly multiplied by reduceSpeedOnConstViolation. - * - * @param pos the current particle position - * @param velocity the current particle velocity to be modified - * @param range the range array - */ - protected void ensureConstraints(double[] pos, double[] velocity, double[][] range) { - double[] newPos = new double[pos.length]; - for (int i = 0; i < pos.length; i++) newPos[i] = pos[i] + velocity[i]; - if (isOutOfRange(pos, range)) { - System.err.println("warning, ensureConstraints called with already violating position (PSO)... reinitializing particle."); - for (int i=0; i range[i][1]))) { - velocity[i] *= -1; // bounce only if leaving in this direction. - } - newPos[i] = pos[i]+velocity[i]; - } else { - // set vel. to land on the bounds - velocity[i] = (newPos[i] < range[i][0]) ? (range[i][0]-pos[i]) : (range[i][1]-pos[i]); - newPos[i] = pos[i]+velocity[i]; - if ((newPos[i] < range[i][0]) || (newPos[i] > range[i][1])) { - velocity[i]*=.999; /// beware of floating point errors. - newPos[i] = pos[i]+velocity[i]; - } - } - while ((newPos[i] < range[i][0]) || (newPos[i] > range[i][1])) { - //System.err.println("missed, pos was " + pos[i] + " vel was "+velocity[i]); - velocity[i]*=reduceSpeedOnConstViolation; - newPos[i] = pos[i]+velocity[i]; - } - } - } - if (isOutOfRange(newPos, range)) { - System.err.println("narg, still out of range"); - } - } + /** + * Makes sure that the future position (after adding velocity to pos) + * remains inside the range array. Therefore, the velocity may be repeatedly + * multiplied by reduceSpeedOnConstViolation. + * + * @param pos the current particle position + * @param velocity the current particle velocity to be modified + * @param range the range array + */ + protected void ensureConstraints(double[] pos, double[] velocity, double[][] range) { + double[] newPos = new double[pos.length]; + for (int i = 0; i < pos.length; i++) { + newPos[i] = pos[i] + velocity[i]; + } + if (isOutOfRange(pos, range)) { + System.err.println("warning, ensureConstraints called with already violating position (PSO)... reinitializing particle."); + for (int i = 0; i < pos.length; i++) { + if (!Mathematics.isInRange(pos[i], range[i][0], range[i][1])) { + pos[i] = RNG.randomDouble(range[i][0], range[i][1]); + } + } + } + for (int i = 0; i < pos.length; i++) { + if (!Mathematics.isInRange(newPos[i], range[i][0], range[i][1])) { + if ((pos[i] == range[i][0]) || (pos[i] == range[i][1])) { + // bounce? + velocity[i] *= reduceSpeedOnConstViolation; // bounce velocity and reduce + if (((pos[i] == range[i][0]) && (newPos[i] < range[i][0])) || ((pos[i] == range[i][1]) && (newPos[i] > range[i][1]))) { + velocity[i] *= -1; // bounce only if leaving in this direction. + } + newPos[i] = pos[i] + velocity[i]; + } else { + // set vel. to land on the bounds + velocity[i] = (newPos[i] < range[i][0]) ? (range[i][0] - pos[i]) : (range[i][1] - pos[i]); + newPos[i] = pos[i] + velocity[i]; + if ((newPos[i] < range[i][0]) || (newPos[i] > range[i][1])) { + velocity[i] *= .999; /// beware of floating point errors. + newPos[i] = pos[i] + velocity[i]; + } + } + while ((newPos[i] < range[i][0]) || (newPos[i] > range[i][1])) { + //System.err.println("missed, pos was " + pos[i] + " vel was "+velocity[i]); + velocity[i] *= reduceSpeedOnConstViolation; + newPos[i] = pos[i] + velocity[i]; + } + } + } + if (isOutOfRange(newPos, range)) { + System.err.println("narg, still out of range"); + } + } - public void optimize() { + public void optimize() { // System.out.println(">>> " + m_Population.getStringRepresentation()); - startOptimize(); + startOptimize(); - // Update the individuals - updatePopulation(); + // Update the individuals + updatePopulation(); - // evaluate the population - this.evaluatePopulation(this.m_Population); - - // update the individual memory - updateSwarmMemory(m_Population); + // evaluate the population + this.evaluatePopulation(this.m_Population); - // log the best individual of the population - logBestIndividual(); + // update the individual memory + updateSwarmMemory(m_Population); + + // log the best individual of the population + logBestIndividual(); // System.out.println("<<< " + m_Population.getStringRepresentation()); - + // if (doLocalSearch && (m_Population.getGeneration()%localSearchGens==0)) { //// System.out.println("Local search at gen "+m_Population.getGeneration()); // Population bestN = m_Population.getBestNIndividuals(Math.max(1,(int)(lsCandidateRatio*m_Population.size()))); @@ -1289,154 +1388,164 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // } else m_Population.incrFunctionCallsBy(maxSteps); // } - this.firePropertyChangedEvent(Population.nextGenerationPerformed); + this.firePropertyChangedEvent(Population.nextGenerationPerformed); + + if (sleepTime > 0) { + try { + Thread.sleep(sleepTime); + } catch (Exception e) { + } + } - if (sleepTime > 0 ) try { Thread.sleep(sleepTime); } catch(Exception e) {} - // maybeClearPlot(); - } + } - protected void maybeClearPlot() { - if (((m_Population.getGeneration() % 23) == 0) && isShow() && (m_Plot != null)) { - m_Plot.clearAll(); - InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)this.m_Population.get(0); - double[][] range = indy.getDoubleRange(); - m_Plot.setCornerPoints(range, 0); - } - } + protected void maybeClearPlot() { + if (((m_Population.getGeneration() % 23) == 0) && isShow() && (m_Plot != null)) { + m_Plot.clearAll(); + InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble) this.m_Population.get(0); + double[][] range = indy.getDoubleRange(); + m_Plot.setCornerPoints(range, 0); + } + } - /** - * Do some preparations in the beginning of the loop. - * - */ - protected void startOptimize() { - if (TRACE) { - for (int i=0; i=2)) Arrays.sort(sortedPop, new AbstractEAIndividualComparator()); - else Arrays.sort(sortedPop, new AbstractEAIndividualComparator(partBestFitKey)); - addSortedIndicesTo(sortedPop, pop); - } - if (topology == PSOTopologyEnum.multiSwarm) { - // prepare multi swarm topology - PhenotypeMetric metric = new PhenotypeMetric(); - Vector leaders = new Vector(pop.size()); - int cur = 0; - boolean found = false, superfluous = false; - double dist; - while (cur < pop.size()) { - found = false; - superfluous = false; - for (int i=0; i dist) { // a formal leader is found - int sSize = (Integer)(leaders.get(i)).getData(multiSwSizeKey); - if ((maxSubSwarmSize > 0) && (sSize >= maxSubSwarmSize)) { - // swarm is too big already - superfluous = true; // toggle reinitialize - found = true; - break; - } else { - found = true; - // assign to leader, update swarm size - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwTypeKey, leaders.get(i)); - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwSizeKey, new Integer(-1)); - leaders.get(i).putData(multiSwSizeKey, 1+sSize); - break; - } - } - } - if (!found) { // new leader is found - leaders.add(((AbstractEAIndividual)sortedPop[cur])); - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwTypeKey, sortedPop[cur]); - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwSizeKey, new Integer(1)); - } else if (superfluous) { - //System.out.println("reinitializing " + cur); - ((AbstractEAIndividual)sortedPop[cur]).putData(partTypeKey, resetType); - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwTypeKey, sortedPop[cur]); - ((AbstractEAIndividual)sortedPop[cur]).putData(multiSwSizeKey, new Integer(1)); - } - cur++; - } + if (topology == PSOTopologyEnum.dms) { // Dynamic multi-swarm after Liang & Suganthan + if (pop.getGeneration() % getDmsRegroupGens() == 0) { + dmsLinks = regroupSwarm(pop, getTopologyRange()); + } + } + if ((topology == PSOTopologyEnum.multiSwarm) || (topology == PSOTopologyEnum.tree)) { + sortedPop = pop.toArray(); + if ((topology == PSOTopologyEnum.multiSwarm) || (treeStruct >= 2)) { + Arrays.sort(sortedPop, new AbstractEAIndividualComparator()); + } else { + Arrays.sort(sortedPop, new AbstractEAIndividualComparator(partBestFitKey)); + } + addSortedIndicesTo(sortedPop, pop); + } + if (topology == PSOTopologyEnum.multiSwarm) { + // prepare multi swarm topology + PhenotypeMetric metric = new PhenotypeMetric(); + Vector leaders = new Vector(pop.size()); + int cur = 0; + boolean found = false, superfluous = false; + double dist; + while (cur < pop.size()) { + found = false; + superfluous = false; + for (int i = 0; i < leaders.size(); i++) { + dist = metric.distance((AbstractEAIndividual) sortedPop[cur], leaders.get(i)); + //System.out.println("dist is "+dist); + if ((m_swarmRadius * 2.) > dist) { // a formal leader is found + int sSize = (Integer) (leaders.get(i)).getData(multiSwSizeKey); + if ((maxSubSwarmSize > 0) && (sSize >= maxSubSwarmSize)) { + // swarm is too big already + superfluous = true; // toggle reinitialize + found = true; + break; + } else { + found = true; + // assign to leader, update swarm size + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwTypeKey, leaders.get(i)); + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwSizeKey, new Integer(-1)); + leaders.get(i).putData(multiSwSizeKey, 1 + sSize); + break; + } + } + } + if (!found) { // new leader is found + leaders.add(((AbstractEAIndividual) sortedPop[cur])); + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwTypeKey, sortedPop[cur]); + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwSizeKey, new Integer(1)); + } else if (superfluous) { + //System.out.println("reinitializing " + cur); + ((AbstractEAIndividual) sortedPop[cur]).putData(partTypeKey, resetType); + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwTypeKey, sortedPop[cur]); + ((AbstractEAIndividual) sortedPop[cur]).putData(multiSwSizeKey, new Integer(1)); + } + cur++; + } // for (int i=0; imetric.distance((AbstractEAIndividual)pop.get(i), (AbstractEAIndividual)pop.get(index)))) { // this.compareAndSet(localBestFitness, localBestPosition, (AbstractEAIndividual)pop.get(i)); @@ -1447,23 +1556,23 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // m_Population.indexOf(leaders.get(i)); // System.out.print("s " + i + " w " + sSize + " (" + m_Population.indexOf(leaders.get(i)) + "), "); // } - //System.out.println(" -- best " + m_Population.indexOf(m_Population.getBestEAIndividual())); - } - if (topology == PSOTopologyEnum.hpso) { // HPSO sorting the population - int parentIndex; - AbstractEAIndividual indy; - AbstractEAIndividualComparator comp = new AbstractEAIndividualComparator(partBestFitKey); - for (int i=0; i regroupSwarm(Population pop, int groupSize) { - int numGroups = pop.size() / groupSize; // truncated integer: last group is larger - int[] perm = RNG.randomPerm(pop.size()); - - Vector links = new Vector(numGroups); - for (int i=0; i regroupSwarm(Population pop, int groupSize) { + int numGroups = pop.size() / groupSize; // truncated integer: last group is larger + int[] perm = RNG.randomPerm(pop.size()); + + Vector links = new Vector(numGroups); + for (int i = 0; i < numGroups; i++) { + if (i < numGroups - 1) { + links.add(new int[groupSize]); + } else { + links.add(new int[pop.size() - (groupSize * i)]); // the last group is larger + } + int[] group = links.get(i); + for (int k = 0; k < group.length; k++) { + group[k] = perm[groupSize * i + k]; + pop.getEAIndividual(group[k]).putData(dmsGroupIndexKey, i); + } + } + return links; + } // /** // * Randomly assign groups of size groupSize. @@ -1534,431 +1646,507 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // } // return perm; // } - - /** - * This method is simply for debugging. - */ - protected void show() { - if (this.m_Plot == null) { - InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble)this.m_Population.get(0); - double[][] range = indy.getDoubleRange(); - this.m_Plot = new eva2.gui.Plot("PSO "+ m_Population.getGeneration(), "x1", "x2", range[0], range[1]); + /** + * This method is simply for debugging. + */ + protected void show() { + if (this.m_Plot == null) { + InterfaceDataTypeDouble indy = (InterfaceDataTypeDouble) this.m_Population.get(0); + double[][] range = indy.getDoubleRange(); + this.m_Plot = new eva2.gui.Plot("PSO " + m_Population.getGeneration(), "x1", "x2", range[0], range[1]); // this.m_Plot.setUnconnectedPoint(range[0][0], range[1][0], 0); // this.m_Plot.setUnconnectedPoint(range[0][1], range[1][1], 0); - } - } + } + } - public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { - this.m_Listener = ea; - } - public boolean removePopulationChangedEventListener( - InterfacePopulationChangedEventListener ea) { - if (m_Listener==ea) { - m_Listener=null; - return true; - } else return false; - } - protected void firePropertyChangedEvent (String name) { - if (this.m_Listener != null) this.m_Listener.registerPopulationStateChanged(this, name); - } + public void addPopulationChangedEventListener(InterfacePopulationChangedEventListener ea) { + this.m_Listener = ea; + } - /** This method will set the problem that is to be optimized - * @param problem - */ - public void SetProblem (InterfaceOptimizationProblem problem) { - this.m_Problem = problem; - } - public InterfaceOptimizationProblem getProblem () { - return this.m_Problem; - } + public boolean removePopulationChangedEventListener( + InterfacePopulationChangedEventListener ea) { + if (m_Listener == ea) { + m_Listener = null; + return true; + } else { + return false; + } + } - /** This method will return a string describing all properties of the optimizer - * and the applied methods. - * @return A descriptive string - */ - public String getStringRepresentation() { - String result = ""; - result += "Particle Swarm Optimization:\n"; - result += "Optimization Problem: "; - result += this.m_Problem.getStringRepresentationForProblem(this) +"\n"; - result += this.m_Population.getStringRepresentation(); - return result; - } - - /** This method allows you to set an identifier for the algorithm - * @param name The indenifier - */ - public void SetIdentifier(String name) { - this.m_Identifier = name; - } - - public String getIdentifier() { - return this.m_Identifier; - } + protected void firePropertyChangedEvent(String name) { + if (this.m_Listener != null) { + this.m_Listener.registerPopulationStateChanged(this, name); + } + } - /** This method is required to free the memory on a RMIServer, - * but there is nothing to implement. - */ - public void freeWilly() { + /** + * This method will set the problem that is to be optimized + * + * @param problem + */ + public void SetProblem(InterfaceOptimizationProblem problem) { + this.m_Problem = problem; + } - } - /********************************************************************************************************************** - * These are for GUI - */ - /** This method returns a global info string - * @return description - */ - public static String globalInfo() { - return "Particle Swarm Optimization by Kennedy and Eberhart."; - } - /** This method will return a naming String - * @return The name of the algorithm - */ - public String getName() { + public InterfaceOptimizationProblem getProblem() { + return this.m_Problem; + } + + /** + * This method will return a string describing all properties of the + * optimizer and the applied methods. + * + * @return A descriptive string + */ + public String getStringRepresentation() { + String result = ""; + result += "Particle Swarm Optimization:\n"; + result += "Optimization Problem: "; + result += this.m_Problem.getStringRepresentationForProblem(this) + "\n"; + result += this.m_Population.getStringRepresentation(); + return result; + } + + /** + * This method allows you to set an identifier for the algorithm + * + * @param name The indenifier + */ + public void SetIdentifier(String name) { + this.m_Identifier = name; + } + + public String getIdentifier() { + return this.m_Identifier; + } + + /** + * This method is required to free the memory on a RMIServer, but there is + * nothing to implement. + */ + public void freeWilly() { + } + + /** + * ******************************************************************************************************************** + * These are for GUI + */ + /** + * This method returns a global info string + * + * @return description + */ + public static String globalInfo() { + return "Particle Swarm Optimization by Kennedy and Eberhart."; + } + + /** + * This method will return a naming String + * + * @return The name of the algorithm + */ + public String getName() { // return "PSO-"+getTopology()+getTopologyRange()+(isDoLocalSearch() ? "-ls_" : "_")+getPhi1()+"_"+getPhi2(); - return "PSO-"+getTopology()+getTopologyRange()+"_"+getPhi1()+"_"+getPhi2(); - } + return "PSO-" + getTopology() + getTopologyRange() + "_" + getPhi1() + "_" + getPhi2(); + } + + public Population getPopulation() { + return this.m_Population; + } + + public void setPopulation(Population pop) { + this.m_Population = pop; + if (pop.size() != pop.getTargetSize()) { // new particle count! + tracedVelocity = null; + initByPopulation(null, false); + } else { + for (int i = 0; i < pop.size(); i++) { + AbstractEAIndividual indy = pop.getEAIndividual(i); + if (indy == null) { + System.err.println("Error in PSO.setPopulation!"); + } else if (!indy.hasData(partTypeKey)) { + initIndividualDefaults(indy, m_InitialVelocity); + initIndividualMemory(indy); + indy.putData(indexKey, i); + indy.SetIndividualIndex(i); + if (TRACE) { + System.err.println("init indy " + i + " " + AbstractEAIndividual.getDefaultDataString(indy)); + } + } + } + } + m_BestIndividual = pop.getBestEAIndividual(); + } + + public String populationTipText() { + return "Edit the properties of the population used."; + } - public Population getPopulation() { - return this.m_Population; - } - public void setPopulation(Population pop){ - this.m_Population = pop; - if (pop.size() != pop.getTargetSize()) { // new particle count! - tracedVelocity = null; - initByPopulation(null, false); - } else for (int i=0; i 1) k = 1; - this.m_SpeedLimit = k; - } - - public double getSpeedLimit() { - return this.m_SpeedLimit; - } - - /** - * It may be useful to give each particle a different speed limit. - * - * @param index - * @return - */ - protected double getSpeedLimit(int index) { - return this.m_SpeedLimit; - } - - public String speedLimitTipText() { - return "The speed limit in respect to the size of the search space [0,1]."; - } + /** + * This method will set the initial velocity + * + * @param f + */ + public void setInitialVelocity(double f) { + this.m_InitialVelocity = f; + } - /** - * Set the phi values as well as the inertness parameter so as to resemble the constriction scheme. - * The constriction scheme calculates the speed update in the following - * way: v(t+1) = Chi * ( v(t) + tau1*u1*(p-x(t)) * tau2*u2*(g-x(t))) - * with u1, u2 random variables in (0,1) and tau1 and tau2 usually set to 2.05. The sum tau1 and tau2 - * must be greater than 4. The Chi parameter (constriction) is set as in - * 2 - * Chi = ------------------------ - * |2-tau-sqrt(tau^2-4 tau)| - * where tau = tau1 + tau2 - * See Clerc&Kennedy: The Particle Swarm: Explosion, stability and convergence, 2002. - * - * @param tau1 - * @param tau2 - */ - protected void setConstriction(double tau1, double tau2) { - double pSum = tau1+tau2; - if (pSum <= 4) { - System.err.println("error, invalid tauSum value in PSO::setConstriction"); - } else { - if (!getAlgoType().isSelectedString("Constriction")) System.err.println("Warning, PSO algorithm variant constriction expected!"); - m_Phi1=tau1; - m_Phi2=tau2; - setInertnessOrChi(2./(Math.abs(2-pSum-Math.sqrt((pSum*pSum)-(4*pSum))))); - } - } + public double getInitialVelocity() { + return this.m_InitialVelocity; + } - /** - * This method will set the inertness/chi value - * @param k - */ - public void setInertnessOrChi(double k) { - this.m_InertnessOrChi = k; - } + public String initialVelocityTipText() { + return "The initial velocity for each PSO particle."; + } - public double getInertnessOrChi() { - return this.m_InertnessOrChi; - } - public String inertnessOrChiTipText() { - return "Gives the speed decay of the previous velocity [0,1] in inertness mode or the chi value in constriction mode which is calculated from phi1 and phi2."; - } + /** + * This method will set the speed limit + * + * @param k + */ + public void setSpeedLimit(double k) { + if (k < 0) { + k = 0; + } + if (k > 1) { + k = 1; + } + this.m_SpeedLimit = k; + } - /** This method will set greediness to move towards the best cognition - * @param l - */ - public void setPhi1 (double l) { - this.m_Phi1 = l; - if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2()); - } - public double getPhi1() { - return this.m_Phi1; - } - public String phi1TipText() { - return "Acceleration for the cognition model."; - } + public double getSpeedLimit() { + return this.m_SpeedLimit; + } - /** This method will set greediness to move towards the best social - * @param l - */ - public void setPhi2 (double l) { - this.m_Phi2 = l; - if (algType.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2()); - } - public double getPhi2() { - return this.m_Phi2; - } - public String phi2TipText() { - return "Acceleration for the social model."; - } + /** + * It may be useful to give each particle a different speed limit. + * + * @param index + * @return + */ + protected double getSpeedLimit(int index) { + return this.m_SpeedLimit; + } - /** - * Set the phi1 / phi2 parameter values (and in the constriction variant, adapt constriction factor). - * - * @param phi1 - * @param phi2 - */ - public void setPhiValues(double phi1, double phi2) { - m_Phi1 = phi1; - m_Phi2 = phi2; - if (algType.isSelectedString("Constriction")) setConstriction(phi1, phi2); - } - - /** - * Directly set all parameter values phi1, phi2 and inertness/constriction factor. - * - * @param phi1 - * @param phi2 - * @param inertness - */ - public void setParameterValues(double phi1, double phi2, double inertness) { - m_Phi1 = phi1; - m_Phi2 = phi2; - setInertnessOrChi(inertness); - } - - /** This method allows you to choose the topology type. - * @param s The type. - */ - public void setTopology(PSOTopologyEnum t) { - this.topology = t; - setGOEShowProperties(getClass()); - } - - public void setGOEShowProperties(Class cls) { + public String speedLimitTipText() { + return "The speed limit in respect to the size of the search space [0,1]."; + } + + /** + * Set the phi values as well as the inertness parameter so as to resemble + * the constriction scheme. The constriction scheme calculates the speed + * update in the following way: v(t+1) = Chi * ( v(t) + tau1*u1*(p-x(t)) * + * tau2*u2*(g-x(t))) with u1, u2 random variables in (0,1) and tau1 and tau2 + * usually set to 2.05. The sum tau1 and tau2 must be greater than 4. The + * Chi parameter (constriction) is set as in 2 Chi = + * ------------------------ |2-tau-sqrt(tau^2-4 tau)| where tau = tau1 + + * tau2 See Clerc&Kennedy: The Particle Swarm: Explosion, stability and + * convergence, 2002. + * + * @param tau1 + * @param tau2 + */ + protected void setConstriction(double tau1, double tau2) { + double pSum = tau1 + tau2; + if (pSum <= 4) { + System.err.println("error, invalid tauSum value in PSO::setConstriction"); + } else { + if (!getAlgoType().isSelectedString("Constriction")) { + System.err.println("Warning, PSO algorithm variant constriction expected!"); + } + m_Phi1 = tau1; + m_Phi2 = tau2; + setInertnessOrChi(2. / (Math.abs(2 - pSum - Math.sqrt((pSum * pSum) - (4 * pSum))))); + } + } + + /** + * This method will set the inertness/chi value + * + * @param k + */ + public void setInertnessOrChi(double k) { + this.m_InertnessOrChi = k; + } + + public double getInertnessOrChi() { + return this.m_InertnessOrChi; + } + + public String inertnessOrChiTipText() { + return "Gives the speed decay of the previous velocity [0,1] in inertness mode or the chi value in constriction mode which is calculated from phi1 and phi2."; + } + + /** + * This method will set greediness to move towards the best cognition + * + * @param l + */ + public void setPhi1(double l) { + this.m_Phi1 = l; + if (algType.getSelectedTag().getID() == 1) { + setConstriction(getPhi1(), getPhi2()); + } + } + + public double getPhi1() { + return this.m_Phi1; + } + + public String phi1TipText() { + return "Acceleration for the cognition model."; + } + + /** + * This method will set greediness to move towards the best social + * + * @param l + */ + public void setPhi2(double l) { + this.m_Phi2 = l; + if (algType.getSelectedTag().getID() == 1) { + setConstriction(getPhi1(), getPhi2()); + } + } + + public double getPhi2() { + return this.m_Phi2; + } + + public String phi2TipText() { + return "Acceleration for the social model."; + } + + /** + * Set the phi1 / phi2 parameter values (and in the constriction variant, + * adapt constriction factor). + * + * @param phi1 + * @param phi2 + */ + public void setPhiValues(double phi1, double phi2) { + m_Phi1 = phi1; + m_Phi2 = phi2; + if (algType.isSelectedString("Constriction")) { + setConstriction(phi1, phi2); + } + } + + /** + * Directly set all parameter values phi1, phi2 and inertness/constriction + * factor. + * + * @param phi1 + * @param phi2 + * @param inertness + */ + public void setParameterValues(double phi1, double phi2, double inertness) { + m_Phi1 = phi1; + m_Phi2 = phi2; + setInertnessOrChi(inertness); + } + + /** + * This method allows you to choose the topology type. + * + * @param s The type. + */ + public void setTopology(PSOTopologyEnum t) { + this.topology = t; + setGOEShowProperties(getClass()); + } + + public void setGOEShowProperties(Class cls) { // this.m_Topology = new SelectedTag( "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" ); - - // linear, grid, random - GenericObjectEditor.setShowProperty(cls, "topologyRange", (topology==PSOTopologyEnum.linear) || (topology==PSOTopologyEnum.grid) || (topology==PSOTopologyEnum.random) || (topology==PSOTopologyEnum.tree) || (topology==PSOTopologyEnum.hpso) || (topology==PSOTopologyEnum.dms)); - // multi swarm - GenericObjectEditor.setShowProperty(cls, "subSwarmRadius", (topology==PSOTopologyEnum.multiSwarm)); - // multi swarm - GenericObjectEditor.setShowProperty(cls, "maxSubSwarmSize", (topology==PSOTopologyEnum.multiSwarm)); - // tree - GenericObjectEditor.setShowProperty(cls, "treeStruct", (topology==PSOTopologyEnum.tree)); - // tree, hpso + + // linear, grid, random + GenericObjectEditor.setShowProperty(cls, "topologyRange", (topology == PSOTopologyEnum.linear) || (topology == PSOTopologyEnum.grid) || (topology == PSOTopologyEnum.random) || (topology == PSOTopologyEnum.tree) || (topology == PSOTopologyEnum.hpso) || (topology == PSOTopologyEnum.dms)); + // multi swarm + GenericObjectEditor.setShowProperty(cls, "subSwarmRadius", (topology == PSOTopologyEnum.multiSwarm)); + // multi swarm + GenericObjectEditor.setShowProperty(cls, "maxSubSwarmSize", (topology == PSOTopologyEnum.multiSwarm)); + // tree + GenericObjectEditor.setShowProperty(cls, "treeStruct", (topology == PSOTopologyEnum.tree)); + // tree, hpso // GenericObjectEditor.setShowProperty(cls, "treeBranchDegree", (topology==PSOTopologyEnum.tree) || (topology==PSOTopologyEnum.hpso)); - // linear - GenericObjectEditor.setShowProperty(cls, "wrapTopology", (topology==PSOTopologyEnum.linear) || (topology==PSOTopologyEnum.grid)); - // dms - GenericObjectEditor.setShowProperty(cls, "dmsRegroupGens", (topology==PSOTopologyEnum.dms)); - } - - public PSOTopologyEnum getTopology() { - return topology; - } - public String topologyTipText() { - return "Choose the topology type"; - } + // linear + GenericObjectEditor.setShowProperty(cls, "wrapTopology", (topology == PSOTopologyEnum.linear) || (topology == PSOTopologyEnum.grid)); + // dms + GenericObjectEditor.setShowProperty(cls, "dmsRegroupGens", (topology == PSOTopologyEnum.dms)); + } - /** This method allows you to choose the algorithm type. - * @param s The type. - */ - public void setAlgoType(SelectedTag s) { - this.algType = s; - if (s.getSelectedTag().getID() == 1) setConstriction(getPhi1(), getPhi2()); - } + public PSOTopologyEnum getTopology() { + return topology; + } - public SelectedTag getAlgoType() { - return this.algType; - } + public String topologyTipText() { + return "Choose the topology type"; + } - public String algoTypeTipText() { - return "Choose the inertness or constriction method. Chi is calculated automatically in constriction."; - } + /** + * This method allows you to choose the algorithm type. + * + * @param s The type. + */ + public void setAlgoType(SelectedTag s) { + this.algType = s; + if (s.getSelectedTag().getID() == 1) { + setConstriction(getPhi1(), getPhi2()); + } + } - /** The range of the local neighbourhood. - * @param s The range. - */ - public void setTopologyRange(int s) { - this.m_TopologyRange = s; - } - public int getTopologyRange() { - return this.m_TopologyRange; - } - public String topologyRangeTipText() { - return "The range of the neighborhood topology."; - } + public SelectedTag getAlgoType() { + return this.algType; + } - /** Toggle Check Constraints. - * @param s Check Constraints. - */ - public void setCheckRange(boolean s) { - this.m_CheckRange = s; - } - public boolean isCheckRange() { - return this.m_CheckRange; - } - public String checkRangeTipText() { - return "Toggle whether particles are allowed to leave the range."; - } + public String algoTypeTipText() { + return "Choose the inertness or constriction method. Chi is calculated automatically in constriction."; + } - /** - * @return true if swarm visualization is turned on - **/ - public boolean isShow() { - return m_Show; - } + /** + * The range of the local neighbourhood. + * + * @param s The range. + */ + public void setTopologyRange(int s) { + this.m_TopologyRange = s; + } - /** - * @param set swarm visualization (2D) - **/ - public void setShow(boolean show) { - m_Show = show; - if (!show) m_Plot = null; - } - public String showTipText() { - return "Activate for debugging in 2D"; - } - - /** - * @return the checkSpeedLimit - **/ - public boolean isCheckSpeedLimit() { - return checkSpeedLimit; - } + public int getTopologyRange() { + return this.m_TopologyRange; + } - /** - * @param checkSpeedLimit the checkSpeedLimit to set - **/ - public void setCheckSpeedLimit(boolean checkSpeedLimit) { - this.checkSpeedLimit = checkSpeedLimit; - GenericObjectEditor.setHideProperty(getClass(), "speedLimit", !checkSpeedLimit); - } + public String topologyRangeTipText() { + return "The range of the neighborhood topology."; + } - public String checkSpeedLimitTipText() { - return "if activated, the speed limit is enforced for the particles"; - } + /** + * Toggle Check Constraints. + * + * @param s Check Constraints. + */ + public void setCheckRange(boolean s) { + this.m_CheckRange = s; + } + + public boolean isCheckRange() { + return this.m_CheckRange; + } + + public String checkRangeTipText() { + return "Toggle whether particles are allowed to leave the range."; + } + + /** + * @return true if swarm visualization is turned on + * + */ + public boolean isShow() { + return m_Show; + } + + /** + * @param set swarm visualization (2D) + * + */ + public void setShow(boolean show) { + m_Show = show; + if (!show) { + m_Plot = null; + } + } + + public String showTipText() { + return "Activate for debugging in 2D"; + } + + /** + * @return the checkSpeedLimit + * + */ + public boolean isCheckSpeedLimit() { + return checkSpeedLimit; + } + + /** + * @param checkSpeedLimit the checkSpeedLimit to set + * + */ + public void setCheckSpeedLimit(boolean checkSpeedLimit) { + this.checkSpeedLimit = checkSpeedLimit; + GenericObjectEditor.setHideProperty(getClass(), "speedLimit", !checkSpeedLimit); + } + + public String checkSpeedLimitTipText() { + return "if activated, the speed limit is enforced for the particles"; + } // public int getEMAPeriods() { // return emaPeriods; // } - // public void setEMAPeriods(int emaP) { // this.emaPeriods = emaP; // } + /** + * @return the sleepTime + * + */ + public int getSleepTime() { + return sleepTime; + } - /** - * @return the sleepTime - **/ - public int getSleepTime() { - return sleepTime; - } - /** - * @param sleepTime the sleepTime to set - **/ - public void setSleepTime(int sleepTime) { - this.sleepTime = sleepTime; - } - public String sleepTimeTipText() { - return "Sleep for a time between iterations - to be used with debugging and the show option."; - } - - - public double getSubSwarmRadius() { - return m_swarmRadius; - } + /** + * @param sleepTime the sleepTime to set + * + */ + public void setSleepTime(int sleepTime) { + this.sleepTime = sleepTime; + } - public void setSubSwarmRadius(double radius) { - m_swarmRadius = radius; - } + public String sleepTimeTipText() { + return "Sleep for a time between iterations - to be used with debugging and the show option."; + } - public String subSwarmRadiusTipText() { - return "Define the maximum distance to a swarm leader in the multi-swarm variant"; - } + public double getSubSwarmRadius() { + return m_swarmRadius; + } - public int getMaxSubSwarmSize() { - return maxSubSwarmSize; - } + public void setSubSwarmRadius(double radius) { + m_swarmRadius = radius; + } - public void setMaxSubSwarmSize(int subSize) { - maxSubSwarmSize = subSize; - } + public String subSwarmRadiusTipText() { + return "Define the maximum distance to a swarm leader in the multi-swarm variant"; + } - public String maxSubSwarmSizeTipText() { - return "Maximum size of a sub swarm. Violating particles will be reinitialized. 0 means no limit to the sub swarm size."; - } + public int getMaxSubSwarmSize() { + return maxSubSwarmSize; + } - public int getTreeStruct() { - return treeStruct; - } + public void setMaxSubSwarmSize(int subSize) { + maxSubSwarmSize = subSize; + } + + public String maxSubSwarmSizeTipText() { + return "Maximum size of a sub swarm. Violating particles will be reinitialized. 0 means no limit to the sub swarm size."; + } + + public int getTreeStruct() { + return treeStruct; + } + + public void SetTreeStruct(int treeStruct) { + this.treeStruct = treeStruct; + } - public void SetTreeStruct(int treeStruct) { - this.treeStruct = treeStruct; - } - // This was for testing rotation operators // public boolean isUseAlternative() { // return useAlternative; @@ -1967,88 +2155,96 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // public void setUseAlternative(boolean useAlternative) { // this.useAlternative = useAlternative; // } + public boolean isWrapTopology() { + return wrapTopology; + } - public boolean isWrapTopology() { - return wrapTopology; - } + public void setWrapTopology(boolean wrapTopology) { + this.wrapTopology = wrapTopology; + } - public void setWrapTopology(boolean wrapTopology) { - this.wrapTopology = wrapTopology; - } - - public String wrapTopologyTipText() { - return "Wraps the topology to a ring structure"; - } + public String wrapTopologyTipText() { + return "Wraps the topology to a ring structure"; + } - protected int getEmaPeriods() { - return emaPeriods; - } + protected int getEmaPeriods() { + return emaPeriods; + } - protected void setEmaPeriods(int emaPeriods) { - this.emaPeriods = emaPeriods; - } + protected void setEmaPeriods(int emaPeriods) { + this.emaPeriods = emaPeriods; + } - /** - * This method is necessary to allow access from the Processor. - * @return - */ - public ParameterControlManager getParamControl() { - return paramControl; - } - - public ParamAdaption[] getParameterControl() { - return paramControl.getSingleAdapters(); - } - public void setParameterControl(ParamAdaption[] paramControl) { - this.paramControl.setSingleAdapters(paramControl); - } - public String parameterControlTipText() { - return "You may define dynamic paramter control strategies using the parameter name."; - } + /** + * This method is necessary to allow access from the Processor. + * + * @return + */ + public ParameterControlManager getParamControl() { + return paramControl; + } - /** - * Retrieve the set of personal best positions contained in the given population. - * @param population - * @return - */ - protected Population getPersonalBestPos(Population population) { - Population bests = new Population(population.size()); - AbstractEAIndividual indy = (AbstractEAIndividual)population.getEAIndividual(0).clone(); - if (!indy.hasData(partBestFitKey)) return null; - for (int i=0; i1e-20) { - System.err.println("Warning: mismatching best fitness by " + relDiff); - System.err.println("partInfo: " + i + " - " + getParticleInfo(population.getEAIndividual(i))); - } - if (Math.abs(relDiff)>1e-10) { - System.err.println("partInfo: " + i + " - " + getParticleInfo(population.getEAIndividual(i))); - throw new RuntimeException("Mismatching best fitness!! " + personalBestfit[0] + " vs. " + ((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0]); - } - ((InterfaceDataTypeDouble)indy).SetDoubleGenotype(personalBestPos); - indy.SetFitness(personalBestfit); - bests.add((AbstractEAIndividual)indy.clone()); - } - return bests; - } + public ParamAdaption[] getParameterControl() { + return paramControl.getSingleAdapters(); + } - public int getDmsRegroupGens() { - return dmsRegroupInterval; - } + public void setParameterControl(ParamAdaption[] paramControl) { + this.paramControl.setSingleAdapters(paramControl); + } - public void setDmsRegroupGens(int dmsRegroupInterval) { - this.dmsRegroupInterval = dmsRegroupInterval; - } - - public String dmsRegroupGensTipText() { - return "The number of generations after which new subswarms are randomly formed."; - } + public String parameterControlTipText() { + return "You may define dynamic paramter control strategies using the parameter name."; + } + + /** + * Retrieve the set of personal best positions contained in the given + * population. + * + * @param population + * @return + */ + protected Population getPersonalBestPos(Population population) { + Population bests = new Population(population.size()); + AbstractEAIndividual indy = (AbstractEAIndividual) population.getEAIndividual(0).clone(); + if (!indy.hasData(partBestFitKey)) { + return null; + } + for (int i = 0; i < population.size(); i++) { + double[] personalBestPos = (double[]) population.getEAIndividual(i).getData(partBestPosKey); + double[] personalBestfit = (double[]) population.getEAIndividual(i).getData(partBestFitKey); + + double relDiff; + if (personalBestfit[0] != 0) { + relDiff = (personalBestfit[0] - ((InterfaceProblemDouble) m_Problem).eval(personalBestPos)[0]) / personalBestfit[0]; + } else { + relDiff = (personalBestfit[0] - ((InterfaceProblemDouble) m_Problem).eval(personalBestPos)[0]); // absolute diff in this case + }// if (personalBestfit[0]!=((InterfaceProblemDouble)m_Problem).eval(personalBestPos)[0]) { + if (Math.abs(relDiff) > 1e-20) { + System.err.println("Warning: mismatching best fitness by " + relDiff); + System.err.println("partInfo: " + i + " - " + getParticleInfo(population.getEAIndividual(i))); + } + if (Math.abs(relDiff) > 1e-10) { + System.err.println("partInfo: " + i + " - " + getParticleInfo(population.getEAIndividual(i))); + throw new RuntimeException("Mismatching best fitness!! " + personalBestfit[0] + " vs. " + ((InterfaceProblemDouble) m_Problem).eval(personalBestPos)[0]); + } + ((InterfaceDataTypeDouble) indy).SetDoubleGenotype(personalBestPos); + indy.SetFitness(personalBestfit); + bests.add((AbstractEAIndividual) indy.clone()); + } + return bests; + } + + public int getDmsRegroupGens() { + return dmsRegroupInterval; + } + + public void setDmsRegroupGens(int dmsRegroupInterval) { + this.dmsRegroupInterval = dmsRegroupInterval; + } + + public String dmsRegroupGensTipText() { + return "The number of generations after which new subswarms are randomly formed."; + } // public boolean isDoLocalSearch() { // return doLocalSearch; @@ -2057,25 +2253,34 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // public void setDoLocalSearch(boolean doLocalSearch) { // this.doLocalSearch = doLocalSearch; // } + public String[] getAdditionalDataHeader() { + if (emaPeriods > 0) { + return new String[]{"meanEMASpeed", "meanCurSpeed"}; + } else { + return new String[]{"meanCurSpeed"}; + } + } - public String[] getAdditionalDataHeader() { - if (emaPeriods > 0) return new String[]{"meanEMASpeed", "meanCurSpeed"}; - else return new String[]{"meanCurSpeed"}; - } - - public String[] getAdditionalDataInfo() { - if (emaPeriods > 0) return new String[]{"Exponential moving average of the (range-relative) speed of all particles", "The mean (range-relative) current speed of all particles"}; - else return new String[]{"The mean (range-relative) current speed of all particles"}; - } + public String[] getAdditionalDataInfo() { + if (emaPeriods > 0) { + return new String[]{"Exponential moving average of the (range-relative) speed of all particles", "The mean (range-relative) current speed of all particles"}; + } else { + return new String[]{"The mean (range-relative) current speed of all particles"}; + } + } - public Object[] getAdditionalDataValue(PopulationInterface pop) { - AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(0); - if (emaPeriods>0) { - double relSp; - if (indy instanceof InterfaceDataTypeDouble) { - relSp = getRelativeEMASpeed(((InterfaceDataTypeDouble)indy).getDoubleRange()); - } else relSp=Double.NaN; - return new Object[]{relSp, getPopulationAvgNormedVelocity((Population) pop)}; - } else return new Object[]{getPopulationAvgNormedVelocity((Population) pop)}; - } + public Object[] getAdditionalDataValue(PopulationInterface pop) { + AbstractEAIndividual indy = (AbstractEAIndividual) pop.get(0); + if (emaPeriods > 0) { + double relSp; + if (indy instanceof InterfaceDataTypeDouble) { + relSp = getRelativeEMASpeed(((InterfaceDataTypeDouble) indy).getDoubleRange()); + } else { + relSp = Double.NaN; + } + return new Object[]{relSp, getPopulationAvgNormedVelocity((Population) pop)}; + } else { + return new Object[]{getPopulationAvgNormedVelocity((Population) pop)}; + } + } } \ No newline at end of file diff --git a/src/eva2/server/modules/Processor.java b/src/eva2/server/modules/Processor.java index 4bcdc34b..02d41366 100644 --- a/src/eva2/server/modules/Processor.java +++ b/src/eva2/server/modules/Processor.java @@ -43,7 +43,7 @@ import javax.swing.JOptionPane; */ public class Processor extends Thread implements InterfaceProcessor, InterfacePopulationChangedEventListener { - private static final Logger logger = Logger.getLogger(EvAInfo.defaultLogger); + private static final Logger LOGGER = Logger.getLogger(Processor.class.getName()); private volatile boolean m_optRunning; private InterfaceStatistics m_Statistics; private InterfaceGOParameters goParams; @@ -56,7 +56,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo private boolean userAborted = false; public void addListener(RemoteStateListener module) { - logger.log( + LOGGER.log( Level.FINEST, "Processor: setting module as listener: " + ((module == null) ? "null" : module.toString())); @@ -107,7 +107,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo public void startOpt() { m_createInitialPopulations = true; if (isOptRunning()) { - logger.log(Level.SEVERE, "Processor is already running."); + LOGGER.log(Level.SEVERE, "Processor is already running."); return; } resPop = null; @@ -132,7 +132,7 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo public void restartOpt() { m_createInitialPopulations = false; if (isOptRunning()) { - logger.log(Level.SEVERE, "Processor is already running."); + LOGGER.log(Level.SEVERE, "Processor is already running."); return; } userAborted = false; @@ -183,13 +183,12 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo errMsg = "check console output for error messages."; } errMsg = "Exception in Processor: " + errMsg; - System.err.println(errMsg); - e.printStackTrace(); + LOGGER.log(Level.SEVERE, e.getMessage(), e); try { JOptionPane.showMessageDialog(null, StringTools.wrapLine(errMsg, 60, 0.2), "Error in Optimization", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { - } catch (Error er) { - }; + } catch (Error error) { + } //m_Statistics.stopOptPerformed(false); setOptRunning(false); // normal finish if (m_ListenerModule != null) {