diff --git a/src/eva2/OptimizerFactory.java b/src/eva2/OptimizerFactory.java index 62b2f2f9..12868e29 100644 --- a/src/eva2/OptimizerFactory.java +++ b/src/eva2/OptimizerFactory.java @@ -39,7 +39,6 @@ import eva2.server.go.operators.terminators.EvaluationTerminator; import eva2.server.go.populations.PBILPopulation; import eva2.server.go.populations.Population; import eva2.server.go.problems.AbstractOptimizationProblem; -import eva2.server.go.problems.B1Problem; import eva2.server.go.strategies.ClusterBasedNichingEA; import eva2.server.go.strategies.ClusteringHillClimbing; import eva2.server.go.strategies.DifferentialEvolution; @@ -57,6 +56,7 @@ import eva2.server.go.strategies.SimulatedAnnealing; import eva2.server.go.strategies.Tribes; import eva2.server.modules.GOParameters; import eva2.server.stat.InterfaceStatistics; +import eva2.tools.math.RNG; /** *

@@ -750,6 +750,7 @@ public class OptimizerFactory { int popSize, AbstractOptimizationProblem problem, long seed, InterfaceTerminator term) { Population pop = new Population(popSize); + RNG.setRandomSeed(seed); problem.initPopulation(pop); return makeParams(opt, pop, problem, seed, term); } diff --git a/src/eva2/client/EvAClient.java b/src/eva2/client/EvAClient.java index 82bc1620..8c920e6d 100644 --- a/src/eva2/client/EvAClient.java +++ b/src/eva2/client/EvAClient.java @@ -25,10 +25,8 @@ import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.beans.BeanInfo; import java.io.Serializable; import java.net.URL; -import java.util.LinkedList; import java.util.Properties; import java.util.Set; import java.util.Vector; @@ -53,18 +51,21 @@ import javax.swing.event.MenuListener; import eva2.EvAInfo; import eva2.gui.BeanInspector; +import eva2.gui.EvATabbedFrameMaker; import eva2.gui.ExtAction; import eva2.gui.HtmlDemo; import eva2.gui.JEFrame; import eva2.gui.JEFrameRegister; import eva2.gui.JExtMenu; -import eva2.gui.EvATabbedFrameMaker; import eva2.gui.LogPanel; import eva2.server.EvAServer; import eva2.server.go.InterfaceGOParameters; import eva2.server.modules.AbstractModuleAdapter; import eva2.server.modules.GenericModuleAdapter; import eva2.server.modules.ModuleAdapter; +import eva2.server.stat.AbstractStatistics; +import eva2.server.stat.InterfaceStatisticsParameter; +import eva2.server.stat.StatsParameter; import eva2.tools.EVAERROR; import eva2.tools.EVAHELP; import eva2.tools.ReflectPackage; @@ -276,6 +277,19 @@ public class EvAClient implements RemoteStateListener, Serializable { new Thread(cp).start(); } + /** + * Try to start the optimization with current parameters on the loaded module. + * Return true on success, otherwise false. + * + * @return + */ + public boolean startOptimization() { + if (currentModuleAdapter!=null) { + currentModuleAdapter.startOpt(); + return true; + } else return false; + } + /** * Sets given hostname and tries to load GOParamsters from given file if non null. */ @@ -704,6 +718,14 @@ public class EvAClient implements RemoteStateListener, Serializable { return null; } + public AbstractStatistics getStatistics() { + return ((GenericModuleAdapter)currentModuleAdapter).getStatistics(); + } + + public InterfaceStatisticsParameter getStatsParams() { + return ((GenericModuleAdapter)currentModuleAdapter).getStatistics().getStatisticsParameter(); + } + /** * Check if there is an optimization currently running. * diff --git a/src/eva2/gui/FunctionArea.java b/src/eva2/gui/FunctionArea.java index 000d032b..54da252a 100644 --- a/src/eva2/gui/FunctionArea.java +++ b/src/eva2/gui/FunctionArea.java @@ -316,11 +316,6 @@ public class FunctionArea extends DArea implements Serializable { for (int j = 1; j < s.length; j++) { // add column data of place holder if no value in this set if ((j-1) < pset.getSize()) s[j] = s[j] + " " + pset.getDPoint(j - 1).y; else s[j] += " #"; -// try { -// s[j] = s[j] + " " + pset.getDPoint(j - 1).y; -// } catch (Exception e) { -// s[j] += " "; -// } } } else System.err.println("error in FunctionArea::exportToAscii"); } diff --git a/src/eva2/gui/Plot.java b/src/eva2/gui/Plot.java index bf9d6e25..835e4744 100644 --- a/src/eva2/gui/Plot.java +++ b/src/eva2/gui/Plot.java @@ -46,6 +46,7 @@ import com.sun.image.codec.jpeg.JPEGImageEncoder; import eva2.EvAInfo; import eva2.tools.chart2d.DPointSet; import eva2.tools.tool.BasicResourceLoader; +import eva2.server.go.populations.Population; /*==========================================================================* * CLASS DECLARATION *==========================================================================*/ @@ -277,6 +278,19 @@ public class Plot implements PlotInterface, Serializable { m_Frame.setVisible(true); } + /** + * Draw a population to the Plot instance. Each individual is annotated with the + * given prefix and its fitness. + * + * @param prefix + * @param pop + */ + public void drawPopulation(String prefix, Population pop) { + for (int i=0; i0) indy.addConstraintViolation(v); break; } + currentIndy=null; + } + + /** + * Some constraints require further information on the individual or work on the + * raw fitness which can be requested using this method. + * + * @return + */ + protected double[] getIndyRawFit(String key) { + return getIndyDblData(AbstractProblemDouble.rawFitKey); + } + + /** + * Some constraints require further information on the individual, such as + * additional individual data. This method uses getData of AbstractEAIndividual + * to try to retrieve a double array. + * + * @return + */ + protected double[] getIndyDblData(String key) { + if (currentIndy!=null) { + Object dat = currentIndy.getData(key); + if (dat!=null && (dat instanceof double[])) return (double[])dat; + else { + System.err.println("Error, invalid call to AbstractConstraint.getRawFitness(). Individual had no raw fitness set."); + return null; + } + } else { + System.err.println("Error, invalid call to AbstractConstraint.getRawFitness(). Individual was unknown."); + return null; + } + } + + /** + * Some constraints require further information on the individual, such as + * additional individual data. This method uses getData of AbstractEAIndividual + * to try to retrieve a stored object. + * + * @return + */ + protected Object getIndyData(String key) { + if (currentIndy!=null) { + return currentIndy.getData(key); + } else { + System.err.println("Error, invalid call to AbstractConstraint.getRawFitness(). Individual was unknown."); + return null; + } } private double getViolationConsideringRelation(double val) { diff --git a/src/eva2/server/go/operators/distancemetric/EuclideanMetric.java b/src/eva2/server/go/operators/distancemetric/EuclideanMetric.java index bee77408..ac4143fa 100644 --- a/src/eva2/server/go/operators/distancemetric/EuclideanMetric.java +++ b/src/eva2/server/go/operators/distancemetric/EuclideanMetric.java @@ -26,8 +26,8 @@ public class EuclideanMetric implements InterfaceDistanceMetric { double[] dIndy1, dIndy2; double result = 0; - dIndy1 = AbstractEAIndividual.getDoublePosition(indy1); - dIndy2 = AbstractEAIndividual.getDoublePosition(indy2); + dIndy1 = AbstractEAIndividual.getDoublePositionShallow(indy1); + dIndy2 = AbstractEAIndividual.getDoublePositionShallow(indy2); for (int i = 0; (i < dIndy1.length) && (i < dIndy2.length); i++) { result += Math.pow((dIndy1[i] - dIndy2[i]), 2); diff --git a/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java b/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java index 59258246..f807eedb 100644 --- a/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java +++ b/src/eva2/server/go/operators/distancemetric/PhenotypeMetric.java @@ -111,7 +111,7 @@ public class PhenotypeMetric implements InterfaceDistanceMetric, java.io.Seriali double[] d1, d2; double[][] r1, r2; double tmpResult = 0, tmp=0; - d1 = ((InterfaceDataTypeDouble) indy1).getDoubleData(); + d1 = ((InterfaceDataTypeDouble) indy1).getDoubleData(); // TODO WithoutUpdate would be much quicker - but in which cases is it up to date? r1 = ((InterfaceDataTypeDouble) indy1).getDoubleRange(); d2 = ((InterfaceDataTypeDouble) indy2).getDoubleData(); r2 = ((InterfaceDataTypeDouble) indy2).getDoubleRange(); diff --git a/src/eva2/server/go/operators/mutation/MutateESRankMuCMA.java b/src/eva2/server/go/operators/mutation/MutateESRankMuCMA.java index 03ae6a6c..1763c671 100644 --- a/src/eva2/server/go/operators/mutation/MutateESRankMuCMA.java +++ b/src/eva2/server/go/operators/mutation/MutateESRankMuCMA.java @@ -98,9 +98,27 @@ class CMAParamSet implements InterfacePopulationChangedEventListener, Serializab * @return */ public static CMAParamSet initCMAParams(CMAParamSet params, int mu, int lambda, Population pop, double initialSigma) { + initCMAParams(params, mu, lambda, pop.getCenter(), ((InterfaceDataTypeDouble)pop.getEAIndividual(0)).getDoubleRange(), initialSigma); + pop.addPopulationChangedEventListener(params); + return params; + } + + /** + * Initializes the CMA parameter set for given mu, lambda and a population. + * The initialSigma parameter is used as initial sigma directly unless it is <0, in + * that case the average range is used as initial sigma. + * + * @param params the CMA parameter set to be used - its data are overwritten + * @param mu ES mu parameter + * @param lambda ES lambda parameter + * @param pop associated Population + * @param initialSigma initial sigma or -1 to indicate the usage of average range + * @return + */ + public static CMAParamSet initCMAParams(CMAParamSet params, int mu, int lambda, double[] center, double[][] range, double initialSigma) { // those are from init: params.firstAdaptionDone = false; - params.range = ((InterfaceDataTypeDouble)pop.getEAIndividual(0)).getDoubleRange(); + params.range = range; int dim = params.range.length; // if (TRACE_1) System.out.println("WCMA init " + dim); @@ -129,8 +147,7 @@ class CMAParamSet implements InterfacePopulationChangedEventListener, Serializab params.sigma = initialSigma; // System.out.println("INitial sigma: "+sigma); params.firstSigma = params.sigma; - params.meanX = pop.getCenter(); // this might be ok? - pop.addPopulationChangedEventListener(params); + params.meanX = center; // this might be ok? return params; } @@ -286,6 +303,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali int mu,lambda; mu = selectedP.size(); lambda = oldGen.size(); + int generation = oldGen.getGeneration(); + if (mu>= lambda) { EVAERROR.errorMsgOnce("Warning: invalid mu/lambda ratio! Setting mu to lambda/2."); mu = lambda/2; @@ -300,9 +319,6 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali params = CMAParamSet.initCMAParams(mu, lambda, oldGen, getInitSigma(oldGen)); } else params = (CMAParamSet)oldGen.getData(cmaParamsKey); } - - int generation = oldGen.getGeneration(); - if (TRACE_1) { System.out.println("WCMA adaptGenerational **********"); // System.out.println("newPop measures: " + BeanInspector.toString(newPop.getPopulationMeasures())); @@ -332,11 +348,16 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali for (int j = 0; j < dim; ++j) { sum += params.mB.get(j,i) * BDz[j]; // times B transposed, (Eq 4) in HK04 } - zVect[i] = sum / Math.sqrt(params.eigenvalues[i]); - if (Double.isInfinite(zVect[i])|| Double.isNaN(zVect[i])) { - System.err.println("Error, infinite zVect entry!"); - zVect[i]=0; // TODO MK - } + if (params.eigenvalues[i]<0) { + EVAERROR.errorMsgOnce("Warning: negative eigenvalue in MutateESRankMuCMA! (possibly multiple cases)"); + zVect[i]=0; + } else { + zVect[i] = sum / Math.sqrt(params.eigenvalues[i]); + if (!checkValidDouble(zVect[i])) { + System.err.println("Error, infinite zVect entry!"); + zVect[i]=0; // TODO MK + } + } } /* cumulation for sigma (ps) using B*z */ @@ -345,7 +366,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali for (int j = 0; j < dim; ++j) sum += params.mB.get(i,j) * zVect[j]; newPathS[i] = (1. - params.c_sig) * params.pathS[i] + Math.sqrt(params.c_sig * (2. - params.c_sig)) * sum; - if (Double.isInfinite(newPathS[i]) || Double.isNaN(newPathS[i])) { + if (!checkValidDouble(newPathS[i])) { System.err.println("Error, infinite pathS!"); } } @@ -386,8 +407,11 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali if (Double.isInfinite(sigFact)) params.sigma *= 10.; // in larger search spaces sigma tends to explode after init. else params.sigma *= sigFact; - testAndCorrectNumerics(params, generation, selectedSorted); - + if (!testAndCorrectNumerics(params, generation, selectedSorted)) { + // parameter seemingly exploded... + params = CMAParamSet.initCMAParams(params, mu, lambda, params.meanX, ((InterfaceDataTypeDouble)oldGen.getEAIndividual(0)).getDoubleRange(), params.firstSigma); + } + if (TRACE_1) { System.out.print("psLen=" + (psNorm) + " "); outputParams(params, mu); @@ -422,10 +446,13 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali /** * Requires selected population to be sorted by fitness. * - * @param iterations - * @param selected + * @param params refering parameter set + * @param iterations number of iterations performed + * @param selected selected population + * @return true if the parameters seem ok or were corrected, false if new parameters must be produced */ - void testAndCorrectNumerics(CMAParamSet params, int iterations, Population selected) { // not much left here + private boolean testAndCorrectNumerics(CMAParamSet params, int iterations, Population selected) { // not much left here + boolean corrected = true; /* Flat Fitness, Test if function values are identical */ if (iterations > 1) { // selected pop is sorted @@ -438,7 +465,8 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali if (!checkValidDouble(params.sigma)) { System.err.println("Error, unstable sigma!"); - params.sigma=params.firstSigma; // MK TODO + corrected = false; +// params.sigma=params.firstSigma; // MK TODO // System.err.println( } @@ -465,6 +493,7 @@ public class MutateESRankMuCMA implements InterfaceMutationGenerational, Seriali } } } + return corrected; } // Test... private boolean nearlySame(double[] bestFitness, double[] worstFitness) { diff --git a/src/eva2/server/go/operators/postprocess/PostProcess.java b/src/eva2/server/go/operators/postprocess/PostProcess.java index 01524dfa..e8bc6ed6 100644 --- a/src/eva2/server/go/operators/postprocess/PostProcess.java +++ b/src/eva2/server/go/operators/postprocess/PostProcess.java @@ -202,10 +202,10 @@ public class PostProcess { Population exclude = new Population(); exclude.add(clusters[j].getBestEAIndividual()); result.add(exclude.getEAIndividual(0)); - result.addAll(clusters[j].getRandNIndividualsExcept(n-1, exclude)); + result.addAll(clusters[j].moveRandNIndividualsExcept(n-1, exclude)); break; case RAND_ONLY: - result.addAll(clusters[j].getRandNIndividuals(n)); + result.addAll(clusters[j].moveRandNIndividuals(n)); break; default: System.err.println("Unknown mode in PostProcess:clusterBest!"); break; } @@ -433,7 +433,7 @@ public class PostProcess { } /** - * Search for a local minimum using nelder mead and return the solution found and the number of steps + * Search for a local minimum using CMA and return the solution found and the number of steps * (evaluations) actually performed. This uses the whole population as starting population for nelder mead * meaning that typically only one best is returned. * Returns the number of function calls really performed by the method; sets the number of function calls @@ -448,10 +448,8 @@ public class PostProcess { * @return */ public static int processWithCMA(Population pop, AbstractOptimizationProblem problem, InterfaceTerminator term, int baseEvals) { -// GOParameters cmaParams = OptimizerFactory.cmaESIPOP(problem); MutateESRankMuCMA mutator = new MutateESRankMuCMA(); mutator.setInitializeSigma(ESMutationInitialSigma.avgInitialDistance); -// mutator. EvolutionStrategies es = OptimizerFactory.createEvolutionStrategy(pop.size()/2, pop.size(), false, mutator, 1., new CrossoverESDefault(), 0., new SelectBestIndividuals(), problem, null); for (int i=0; i0) return maxPerturb; + else { + System.err.println("error, unable to select perturbance value in PostProcess.findNMSPerturb since all candidates are equal. Converged population?!"); + return 0.01; + } + } if (maxPerturb>0) return Math.min(maxPerturb, minDistNeighbour/3.); else return minDistNeighbour/3.; } @@ -1083,9 +1091,9 @@ public class PostProcess { int cnt = pop.size()-1; if (cnt == 0) return 0.; else { - double[] indyPos = AbstractEAIndividual.getDoublePosition(pop.getEAIndividual(index)); + double[] indyPos = AbstractEAIndividual.getDoublePositionShallow(pop.getEAIndividual(index)); for (int i=0; i population.size()) throw new RuntimeException("Error, invalid selection: trying to select more individuals (without replacement) than available in SelectRandom."); + int[] perm = RNG.randomPerm(size); + for (int i=0; i listeners = null; + PopulationInitMethod initMethod = PopulationInitMethod.individualDefault; + transient private ArrayList listeners = null; // transient protected InterfacePopulationChangedEventListener m_Listener = null; // the evaluation interval at which listeners are notified @@ -148,6 +151,15 @@ public class Population extends ArrayList implements PopulationInterface, Clonea return res; } + /** + * Clone the population with shallow copies of the individual. This should be used with care! + * @return + */ + public Population cloneShallowInds() { + Population pop = cloneWithoutInds(); + pop.addAll(this); + return pop; + } /** This method inits the state of the population AFTER the individuals * have been inited by a problem @@ -162,6 +174,13 @@ public class Population extends ArrayList implements PopulationInterface, Clonea this.m_Archive.clear(); this.m_Archive.init(); } + switch (initMethod) { + case individualDefault: + break; + case randomLatinHypercube: + createRLHSampling(this, false); + break; + } firePropertyChangedEvent(Population.populationInitialized); } @@ -183,6 +202,51 @@ public class Population extends ArrayList implements PopulationInterface, Clonea } } + /** + * Create a population instance which distributes the individuals according to + * a random latin hypercube sampling. + * + * @param popSize + * @param template + * @return + */ + public static Population createRLHSampling(int popSize, AbstractEAIndividual template) { + Population pop = new Population(popSize); + pop.add(template); + createRLHSampling(pop, true); + return pop; + } + + /** + * Create a population instance which distributes the individuals according to + * a random latin hypercube sampling. + * + * @param popSize + * @param template + * @return + */ + public static void createRLHSampling(Population pop, boolean fillPop) { + if (pop.size()<=0) { + System.err.println("createRLHSampling needs at least one template individual in the population"); + return; + } + AbstractEAIndividual template = pop.getEAIndividual(0); + if (fillPop && (pop.size() sorted = getSorted(); + ArrayList sorted = getSorted(lastFitCrit); res.clear(); for (int i = skip; i < skip+n; i++) { res.add(sorted.get(i)); @@ -672,6 +736,37 @@ public class Population extends ArrayList implements PopulationInterface, Clonea res.setPopulationSize(res.size()); } + /** + * From the given list, remove all but the first n elements. + * @param n + * @param l + */ + public static List toHead(int n, List l) { + l.subList(n, l.size()).clear(); + return l; + } + + /** + * From the given list, remove all but the last n elements. + * @param n + * @param l + */ + public static List toTail(int n, List l) { + l.subList(0, l.size()-n).clear(); + return l; + } + + /** + * Return a new population containing only the last n elements of the instance. + * @param n + * @param l + */ + public Population toTail(int n) { + Population retPop = new Population(n); + retPop.addAll(subList(0, size()-n)); + return retPop; + } + /** * Set a fitness criterion for sorting procedures. This also affects getBest * @param fitIndex @@ -680,16 +775,35 @@ public class Population extends ArrayList implements PopulationInterface, Clonea getSorted(fitIndex); } +// /** +// * Reuses the last fitness criterion. Avoid having to sort again in several calls without modifications in between. +// * The returned array should not be modified! +// * +// * @return +// */ +// protected ArrayList getSorted() { +// return getSorted(lastFitCrit); +// } + /** - * Reuses the last fitness criterion. Avoid having to sort again in several calls without modifications in between. + * Sort the population returning a new ArrayList. * The returned array should not be modified! * + * @param comp A comparator by which sorting is performed * @return */ - protected ArrayList getSorted() { - return getSorted(lastFitCrit); + public ArrayList getSorted(AbstractEAIndividualComparator comp) { + PriorityQueue sQueue = new PriorityQueue(super.size(), comp); + for (int i = 0; i < super.size(); i++) { + AbstractEAIndividual indy = getEAIndividual(i); + if (indy != null) sQueue.add(indy); + } + ArrayList sArr = new ArrayList(this.size()); + AbstractEAIndividual indy; + while ((indy=sQueue.poll())!=null) sArr.add(indy); + return sArr; } - + /** * Avoids having to sort again in several calls without modifications in between. * The returned array should not be modified! @@ -699,38 +813,57 @@ public class Population extends ArrayList implements PopulationInterface, Clonea */ protected ArrayList getSorted(int fitIndex) { if ((fitIndex != lastFitCrit) || (sortedArr == null) || (super.modCount != lastQModCount)) { - lastFitCrit=fitIndex; // TODO check if this works right? - PriorityQueue sQueue = new PriorityQueue(super.size(), new AbstractEAIndividualComparator(fitIndex)); - for (int i = 0; i < super.size(); i++) { - AbstractEAIndividual indy = getEAIndividual(i); - if (indy != null) sQueue.add(indy); - } + lastFitCrit=fitIndex; + ArrayList sArr = getSorted(new AbstractEAIndividualComparator(fitIndex)); + if (sortedArr==null) sortedArr = sArr; + else { + sortedArr.clear(); + sortedArr.addAll(sArr); + } lastQModCount = super.modCount; - if (sortedArr==null) sortedArr = new ArrayList(this.size()); - else sortedArr.clear(); - AbstractEAIndividual indy; - while ((indy=sQueue.poll())!=null) sortedArr.add(indy); } return sortedArr; } - - /** This method returns n random best individuals from the population. + + /** + * This method retrieves n random individuals from the population and + * returns them within a new population. * * @param n number of individuals to look out for * @return The n best individuals * */ - public List getRandNIndividuals(int n) { - return getRandNIndividualsExcept(n, new Population()); + public Population getRandNIndividuals(int n) { + if (n>=size()) return (Population)clone(); + else { + Population pop = cloneShallowInds(); + Population retPop = cloneWithoutInds(); + moveNInds(n, pop, retPop); + return retPop; + } + } + + /** + * This method removes n random individuals from the population and + * returns them within a new population. + * + * @param n number of individuals to look out for + * @return The n best individuals + * + */ + public Population moveRandNIndividuals(int n) { + return moveRandNIndividualsExcept(n, new Population()); } - /** This method returns the n current best individuals from the population in an object array. + /** + * This method removes n random individuals from the population (excluding the given ones) + * and returns them in a new population instance. * * @param n number of individuals to look out for - * @return The n best individuals + * @return The n random individuals * */ - public Population getRandNIndividualsExcept(int n, Population exclude) { + public Population moveRandNIndividualsExcept(int n, Population exclude) { return moveNInds(n, filter(exclude), new Population()); } @@ -757,7 +890,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea */ public static void moveRandIndFromTo(Population src, Population dst) { int k = RNG.randomInt(src.size()); - dst.add(src.remove(k)); + dst.add(src.removeIndexSwitched(k)); } /** @@ -901,6 +1034,10 @@ public class Population extends ArrayList implements PopulationInterface, Clonea return strB.toString(); } + public String getName() { + return "Population-"+getPopulationSize(); + } + /** * Return a list of individual IDs from the population. * @return @@ -999,6 +1136,27 @@ public class Population extends ArrayList implements PopulationInterface, Clonea return prev; } + /** + * ArrayList does not increase the modCount in set. Why??? + * This method keeps the internally sorted array in synch to minimize complete resorting events. + */ + public Object set(int index, Object element, int fitIndex) { + Object prev = super.set(index, element); + modCount++; + if (lastFitCrit==fitIndex && (lastQModCount==(modCount-1))) { + // if nothing happend between this event and the last sorting by the same criterion... + sortedArr.remove(prev); + int i=0; + AbstractEAIndividualComparator comp = new AbstractEAIndividualComparator(fitIndex); + while (i0) { + i++; + } + sortedArr.add(i, (AbstractEAIndividual)element); + lastQModCount=modCount; + } + return prev; + } + public boolean addIndividual(IndividualInterface ind) { super.add(ind); return true; @@ -1010,10 +1168,12 @@ public class Population extends ArrayList implements PopulationInterface, Clonea * * @param index individual index to be removed */ - public void removeIndexSwitched(int index) { + public AbstractEAIndividual removeIndexSwitched(int index) { + AbstractEAIndividual indy = getEAIndividual(index); int lastIndex = size()-1; if (index < lastIndex) set(index, get(lastIndex)); remove(lastIndex); + return indy; } /** @@ -1095,8 +1255,8 @@ public class Population extends ArrayList implements PopulationInterface, Clonea for (int i = 0; i < this.size(); i++) { for (int j = i+1; j < this.size(); j++) { - if (metric == null) d = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePosition(getEAIndividual(i)), - AbstractEAIndividual.getDoublePosition(getEAIndividual(j))); + if (metric == null) d = PhenotypeMetric.euclidianDistance(AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(i)), + AbstractEAIndividual.getDoublePositionShallow(getEAIndividual(j))); else d = metric.distance((AbstractEAIndividual)this.get(i), (AbstractEAIndividual)this.get(j)); meanDist += d; if (d < minDist) minDist = d; @@ -1110,6 +1270,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea res[1]=0; res[2]=0; } +// System.out.println("0-1-dist: " + BeanInspector.toString(metric.distance((AbstractEAIndividual)this.get(0), (AbstractEAIndividual)this.get(1)))); return res; } @@ -1152,6 +1313,32 @@ public class Population extends ArrayList implements PopulationInterface, Clonea return res; } + /** + * Search for the closest (farthest) individual to the given position. + * Return a Pair of the individuals index and distance. + * If the population is empty, a Pair of (-1,-1) is returned. + * + * @param pos + * @param pop + * @param closestOrFarthest if true, the closest individual is retrieved, otherwise the farthest + * @return + */ + public static Pair getClosestFarthestIndy(double[] pos, Population pop, boolean closestOrFarthest) { + double dist = -1.; + int sel=-1; + for (int i = 0; i < pop.size(); i++) { + AbstractEAIndividual indy = pop.getEAIndividual(i); + double[] indyPos = AbstractEAIndividual.getDoublePositionShallow(indy); + double curDist = PhenotypeMetric.euclidianDistance(pos, indyPos); + if ((dist<0) || (!closestOrFarthest && (dist < curDist)) + || (closestOrFarthest && (dist > curDist))) { + dist = curDist; + sel = i; + } + } + return new Pair(sel,dist); + } + /** * Calculate the average position of the population. * @@ -1161,7 +1348,7 @@ public class Population extends ArrayList implements PopulationInterface, Clonea if (size()==0) EVAERROR.errorMsgOnce("Invalid pop size in DistractingPopulation:getCenter!"); double[] centerPos = AbstractEAIndividual.getDoublePosition(getEAIndividual(0)); for (int i=1; i constraintList = new PropertySelectableList(new AbstractConstraint[]{new GenericConstraint()}); private AbstractConstraint[] constraintArray = new AbstractConstraint[]{new GenericConstraint()}; private boolean withConstraints = false; + public static String rawFitKey="UnconstrainedFitnessValue"; public AbstractProblemDouble() { initTemplate(); @@ -104,7 +106,10 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem if (m_Noise != 0) RNG.addNoise(fitness, m_Noise); // set the fitness setEvalFitness(individual, x, fitness); - if (isWithConstraints()) addConstraints(individual, x); + if (isWithConstraints()) { + individual.putData(rawFitKey, individual.getFitness()); + addConstraints(individual, x); + } } /** @@ -187,7 +192,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem * @param dim * @return the lower bound of the double range in the given dimension */ - protected double getRangeLowerBound(int dim) { + public double getRangeLowerBound(int dim) { return -getDefaultRange(); } @@ -200,7 +205,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem * @param dim * @return the upper bound of the double range in the given dimension */ - protected double getRangeUpperBound(int dim) { + public double getRangeUpperBound(int dim) { return getDefaultRange(); } @@ -369,7 +374,7 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem @Override public String getAdditionalFileStringHeader(PopulationInterface pop) { String superHeader = super.getAdditionalFileStringHeader(pop); - if (isWithConstraints()) return superHeader + " \tNum.Viol. \t Sum.Viol."; + if (isWithConstraints()) return superHeader + " \tRawFit. \tNum.Viol. \t Sum.Viol."; else return superHeader; } @@ -377,8 +382,9 @@ public abstract class AbstractProblemDouble extends AbstractOptimizationProblem public String getAdditionalFileStringValue(PopulationInterface pop) { String superVal = super.getAdditionalFileStringValue(pop); if (isWithConstraints()) { - Pair violation= getConstraintViolation((AbstractEAIndividual)pop.getBestIndividual()); - return superVal + " \t" + violation.head() + " \t" + violation.tail(); + AbstractEAIndividual indy = (AbstractEAIndividual)pop.getBestIndividual(); + Pair violation= getConstraintViolation(indy); + return superVal + " \t" + BeanInspector.toString(indy.getData(rawFitKey)) + " \t" + violation.head() + " \t" + violation.tail(); } else return superVal; } diff --git a/src/eva2/server/go/problems/ConstrPressureVessel.java b/src/eva2/server/go/problems/ConstrPressureVessel.java index 0fc2942b..912113f4 100644 --- a/src/eva2/server/go/problems/ConstrPressureVessel.java +++ b/src/eva2/server/go/problems/ConstrPressureVessel.java @@ -86,7 +86,7 @@ public class ConstrPressureVessel extends AbstractProblemDouble { } @Override - protected double getRangeLowerBound(int dim) { + public double getRangeLowerBound(int dim) { switch (dim) { case 0: case 1: return minThickness/2; @@ -100,7 +100,7 @@ public class ConstrPressureVessel extends AbstractProblemDouble { } @Override - protected double getRangeUpperBound(int dim) { + public double getRangeUpperBound(int dim) { switch (dim) { case 0: case 1: return maxThickness; diff --git a/src/eva2/server/go/problems/ExternalRuntimeProblem.java b/src/eva2/server/go/problems/ExternalRuntimeProblem.java index d85b95b0..0468f9da 100644 --- a/src/eva2/server/go/problems/ExternalRuntimeProblem.java +++ b/src/eva2/server/go/problems/ExternalRuntimeProblem.java @@ -32,8 +32,9 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen protected String m_WorkingDir = ""; protected double m_upperBound = 10; protected double m_lowerBound = 0; + private String additionalArg=""; - // Private Subclass to redirect Streams within an extra Thread to avoid dead + // Private Subclass to redirect Streams within an extra Thread to avoid dead // locks private static class MonitorInputStreamThread extends Thread { private Reader reader; @@ -165,6 +166,9 @@ public class ExternalRuntimeProblem extends AbstractOptimizationProblem implemen try { List parameters=new ArrayList(); parameters.add(this.m_Command); + if (additionalArg!=null && (additionalArg.length()>0)) { + parameters.add(additionalArg); + } for(int i=0;i(); best = getPopulation().getBestEAIndividual(); - dim = AbstractEAIndividual.getDoublePosition(getPopulation().getEAIndividual(0)).length; + dim = AbstractEAIndividual.getDoublePositionShallow(getPopulation().getEAIndividual(0)).length; fitConvTerm = new FitnessConvergenceTerminator(stagThreshold, (isStagnationTimeUserDef()) ? stagTimeArbitrary : calcDefaultStagnationTime(), false, true); // gen. based, absolute getPopulation().addPopulationChangedEventListener(this); diff --git a/src/eva2/server/go/strategies/GeneticAlgorithm.java b/src/eva2/server/go/strategies/GeneticAlgorithm.java index 31bee1fc..fa931494 100644 --- a/src/eva2/server/go/strategies/GeneticAlgorithm.java +++ b/src/eva2/server/go/strategies/GeneticAlgorithm.java @@ -123,9 +123,10 @@ public class GeneticAlgorithm implements InterfaceOptimizer, java.io.Serializabl if (this.m_Population == null) System.out.println("population null "+i); offSprings = tmpIndy.mateWith(this.m_PartnerSelection.findPartnerFor(tmpIndy, this.m_Population, this.m_NumberOfPartners)); - for (int j = 0; j < offSprings.length; j++) { - offSprings[j].mutate(); - } +// for (int j = 0; j < offSprings.length; j++) { +// offSprings[j].mutate(); // quite useless if n-1 are thrown away... +// } + offSprings[0].mutate(); result.add(i, offSprings[0]); } this.evaluatePopulation(result); diff --git a/src/eva2/server/go/strategies/NelderMeadSimplex.java b/src/eva2/server/go/strategies/NelderMeadSimplex.java index 209515f2..9d595540 100644 --- a/src/eva2/server/go/strategies/NelderMeadSimplex.java +++ b/src/eva2/server/go/strategies/NelderMeadSimplex.java @@ -138,7 +138,8 @@ public class NelderMeadSimplex implements InterfaceOptimizer, Serializable, Inte for (int i=0; i dmsLinks = null; protected ParameterControlManager paramControl = new ParameterControlManager(); /** @@ -92,6 +102,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se 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; @@ -110,6 +121,9 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se transient protected boolean m_Show = false; transient protected eva2.gui.Plot m_Plot; + private boolean externalInitialPop = false; +// private double lsCandidateRatio=0.25; + public ParticleSwarmOptimization() { // this.m_Topology = new SelectedTag( "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" ); @@ -143,11 +157,11 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** * 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 - * @param popSize swarm size */ public ParticleSwarmOptimization(int popSize, double p1, double p2, PSOTopologyEnum topo, int topoRange) { this(); @@ -158,6 +172,26 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se topology=topo; } +// /** +// * Constructor for most common parameters with constriction based approach and local search. +// * +// * @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 +// * @param lsEveryNGens interval of local search steps in generations +// * @param stepsPerInd number of local search steps per individual +// * @param candidateRatio ratio of population on which local search is performed +// */ +// public ParticleSwarmOptimization(int popSize, double p1, double p2, PSOTopologyEnum topo, int topoRange, int lsEveryNGens, int stepsPerInd, double candidateRatio) { +// this(popSize, p1, p2, topo, topoRange); +// setDoLocalSearch(true); +// localSearchGens=lsEveryNGens; +// lsStepsPerInd=stepsPerInd; +// lsCandidateRatio = candidateRatio; +// } + public Object clone() { return (Object) new ParticleSwarmOptimization(this); } @@ -180,12 +214,13 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // topoPlot.dispose(); topoPlot = null; } - this.m_Problem.initPopulation(this.m_Population); 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); - initByPopulation(m_Population, false); + initByPopulation(null, false); + externalInitialPop = false; } /** @@ -380,12 +415,17 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se return getPopulationVelSpeed(pop, 2, partVelKey, partTypeKey, defaultType)[0]; } - /** This method will init the optimizer with a given population + /** + * This method will init the optimizer with a given population or, if pop is null, + * initialize the current population as if it was new. * @param pop The initial population * @param reset If true the population is reset. */ public void initByPopulation(Population pop, boolean reset) { - this.m_Population = (Population)pop.clone(); + if (pop != null) { + this.m_Population = (Population)pop.clone(); + externalInitialPop = true; + } if (reset) this.m_Population.init(); AbstractEAIndividual indy; @@ -407,13 +447,19 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se treeLevels = 0; // the HPSO tree will contain layers 0...HPSOLevels, the last one is "incomplete" with only HPSOOrphans number of nodes - while (getMaxNodes(treeBranchDeg, treeLevels) < pop.size()) treeLevels++; - treeOrphans = pop.size()-getMaxNodes(treeBranchDeg, treeLevels-1); - treeLastFullLevelNodeCnt = (int)Math.pow(treeBranchDeg, treeLevels-1); + if (getTopology()==PSOTopologyEnum.hpso || getTopology()==PSOTopologyEnum.tree) { + if (m_TopologyRange<2) System.err.println("Error, tree/hpso requires topology range of at least 2!"); + else { + while (getMaxNodes(m_TopologyRange, treeLevels) < m_Population.size()) treeLevels++; + treeOrphans = m_Population.size()-getMaxNodes(m_TopologyRange, treeLevels-1); + treeLastFullLevelNodeCnt = (int)Math.pow(m_TopologyRange, treeLevels-1); + } + } + if (getTopology()==PSOTopologyEnum.dms) dmsLinks=regroupSwarm(m_Population, getTopologyRange()); } - private boolean defaultsDone(AbstractEAIndividual individual) { - return individual.hasData(indexKey); + private boolean defaultsDone(AbstractEAIndividual indy) { + return (indy.hasData(partVelKey) && indy.hasData(indexKey)); } /** @@ -426,7 +472,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se for (int i = 0; i < pop.size(); i++) { indy = (AbstractEAIndividual) pop.get(i); if (indy instanceof InterfaceDataTypeDouble) { - initIndividualDefaults(indy, m_InitialVelocity); + if (!externalInitialPop || (!defaultsDone(indy))) initIndividualDefaults(indy, m_InitialVelocity); } indy.putData(indexKey, i); indy.SetIndividualIndex(i); @@ -460,6 +506,24 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se //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; i0) { // its found and its not the root. root has no parent to check for - k = getParentIndex(treeBranchDeg, sortedIndex, pop.size()); + 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 = treeBranchDeg*sortedIndex+1; // this is the offset of the nodes children - for (int i=0; i=0) { - k = getParentIndex(treeBranchDeg, index, pop.size()); + 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); @@ -951,6 +1016,18 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se 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 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]; - } + } + 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. } - 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]; + } 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]; + } } - //for (int i = 0; i < pos.length; i++) newPos[i] = pos[i] + velocity[i]; - if (isOutOfRange(newPos, range)) { - System.err.println("narg, still out of range"); - } - -// while (isOutOfRange(newPos, range)) { -// for (int i = 0; i < velocity.length; i++) velocity[i] *= reduceSpeedOnConstViolation; -// for (int i = 0; i < pos.length; i++) newPos[i] = pos[i] + velocity[i]; -// } + } + if (isOutOfRange(newPos, range)) { + System.err.println("narg, still out of range"); } } @@ -1149,6 +1218,26 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // System.out.println(">>> " + m_Population.getBestEAIndividual().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()))); +//// Population bestN = m_Population.getSortedNIndividuals(Math.max(1,(int)(lsCandidateRatio*m_Population.size())), false); +// Population cands=(Population)bestN.clone(); +// int maxSteps=cands.size()*lsStepsPerInd; +// int stepsDone = PostProcess.processSingleCandidates(PostProcessMethod.nelderMead, cands, maxSteps, 0.01, (AbstractOptimizationProblem)this.m_Problem, null); +// for (int i=0; imaxSteps) { +//// System.err.println("Warning: more steps performed than alloed in PSO LS: " + stepsDone + " vs. " + maxSteps); +// m_Population.incrFunctionCallsBy(stepsDone); +// } else m_Population.incrFunctionCallsBy(maxSteps); +// } + this.firePropertyChangedEvent(Population.nextGenerationPerformed); if (sleepTime > 0 ) try { Thread.sleep(sleepTime); } catch(Exception e) {} @@ -1245,7 +1334,11 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se protected void updateTopology(Population pop) { // int topoID = this.m_Topology.getSelectedTag().getID(); // this.m_Topology = new SelectedTag( "Linear", "Grid", "Star", "Multi-Swarm", "Tree", "HPSO", "Random" ); - + 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()); @@ -1312,7 +1405,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se 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=numGroups) groupIndex--; +// pop.getEAIndividual(perm[k]).putData(dmsGroupIndexKey, groupIndex); +// } +// return perm; +// } + /** * This method is simply for debugging. */ @@ -1429,7 +1565,8 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se * @return The name of the algorithm */ public String getName() { - return "PSO-"+getPhi1()+"_"+getPhi2(); +// return "PSO-"+getTopology()+getTopologyRange()+(isDoLocalSearch() ? "-ls_" : "_")+getPhi1()+"_"+getPhi2(); + return "PSO-"+getTopology()+getTopologyRange()+"_"+getPhi1()+"_"+getPhi2(); } /** Assuming that all optimizer will store thier data in a population @@ -1614,7 +1751,7 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // 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)); + 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 @@ -1622,9 +1759,11 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // tree GenericObjectEditor.setShowProperty(cls, "treeStruct", (topology==PSOTopologyEnum.tree)); // tree, hpso - GenericObjectEditor.setShowProperty(cls, "treeBranchDegree", (topology==PSOTopologyEnum.tree) || (topology==PSOTopologyEnum.hpso)); +// GenericObjectEditor.setShowProperty(cls, "treeBranchDegree", (topology==PSOTopologyEnum.tree) || (topology==PSOTopologyEnum.hpso)); // linear GenericObjectEditor.setShowProperty(cls, "wrapTopology", (topology==PSOTopologyEnum.linear)); + // dms + GenericObjectEditor.setShowProperty(cls, "dmsRegroupGens", (topology==PSOTopologyEnum.dms)); } public PSOTopologyEnum getTopology() { @@ -1666,14 +1805,14 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se /** Toggle Check Constraints. * @param s Check Constraints. */ - public void setCheckConstraints(boolean s) { - this.m_CheckConstraints = s; + public void setCheckRange(boolean s) { + this.m_CheckRange = s; } - public boolean isCheckConstraints() { - return this.m_CheckConstraints; + public boolean isCheckRange() { + return this.m_CheckRange; } - public String checkConstraintsTipText() { - return "Toggle constraints check (whether particles are allowed to leave the range)."; + public String checkRangeTipText() { + return "Toggle whether particles are allowed to leave the range."; } /** @@ -1773,18 +1912,6 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se // this.useAlternative = useAlternative; // } - public int getTreeBranchDegree() { - return treeBranchDeg; - } - - public void setTreeBranchDegree(int branch) { - treeBranchDeg = branch; - } - - public String treeBranchDegreeTipText() { - return "Set the branch degree of the tree topology."; - } - public boolean isWrapTopology() { return wrapTopology; } @@ -1829,10 +1956,57 @@ public class ParticleSwarmOptimization implements InterfaceOptimizer, java.io.Se 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 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; +// } +// +// public void setDoLocalSearch(boolean doLocalSearch) { +// this.doLocalSearch = doLocalSearch; +// } + + public String getAdditionalFileStringHeader(PopulationInterface pop) { + if (emaPeriods > 0) return " \tMeanCurSpeed \tMeanEMASpeed"; + else return " \tMeanCurSpeed"; + } + + public String getAdditionalFileStringValue(PopulationInterface pop) { + String res=" \t"; + AbstractEAIndividual indy = (AbstractEAIndividual)pop.get(0); + if (emaPeriods>0) { + if (indy instanceof InterfaceDataTypeDouble) { + res = getRelativeEMASpeed(((InterfaceDataTypeDouble)indy).getDoubleRange()) + " \t"; + } else res=Double.NaN + " \t";; + } + res += getPopulationAvgNormedVelocity((Population) pop); + return res; + } } \ No newline at end of file diff --git a/src/eva2/server/modules/PSOParameters.java b/src/eva2/server/modules/PSOParameters.java index d144ee8f..b7e39124 100644 --- a/src/eva2/server/modules/PSOParameters.java +++ b/src/eva2/server/modules/PSOParameters.java @@ -5,18 +5,12 @@ import java.io.Serializable; import eva2.gui.GenericObjectEditor; import eva2.server.go.InterfaceGOParameters; -import eva2.server.go.InterfacePopulationChangedEventListener; -import eva2.server.go.InterfaceTerminator; import eva2.server.go.enums.PSOTopologyEnum; -import eva2.server.go.operators.selection.InterfaceSelection; import eva2.server.go.operators.terminators.EvaluationTerminator; import eva2.server.go.populations.Population; -import eva2.server.go.problems.B1Problem; import eva2.server.go.problems.F1Problem; -import eva2.server.go.problems.InterfaceOptimizationProblem; import eva2.server.go.strategies.InterfaceOptimizer; import eva2.server.go.strategies.ParticleSwarmOptimization; -import eva2.server.go.strategies.PopulationBasedIncrementalLearning; import eva2.tools.SelectedTag; import eva2.tools.Serializer; @@ -174,14 +168,14 @@ public class PSOParameters extends AbstractGOParameters implements InterfaceGOPa /** Toggle Check Constraints. * @param s Check Constraints. */ - public void setCheckConstraints(boolean s) { - ((ParticleSwarmOptimization)this.m_Optimizer).setCheckConstraints(s); + public void setCheckRange(boolean s) { + ((ParticleSwarmOptimization)this.m_Optimizer).setCheckRange(s); } - public boolean isCheckConstraints() { - return ((ParticleSwarmOptimization)this.m_Optimizer).isCheckConstraints(); + public boolean isCheckRange() { + return ((ParticleSwarmOptimization)this.m_Optimizer).isCheckRange(); } public String checkConstraintsTipText() { - return ((ParticleSwarmOptimization)this.m_Optimizer).checkConstraintsTipText(); + return ((ParticleSwarmOptimization)this.m_Optimizer).checkRangeTipText(); } /** This method allows you to choose the topology type. @@ -264,23 +258,23 @@ public class PSOParameters extends AbstractGOParameters implements InterfaceGOPa return ((ParticleSwarmOptimization)this.m_Optimizer).algoTypeTipText(); } - /** - * @return the treeBranchDeg - */ - public int getTreeBranchDegree() { - return ((ParticleSwarmOptimization)this.m_Optimizer).getTreeBranchDegree(); - } - - /** - * @param treeBranchDeg the treeBranchDeg to set - */ - public void setTreeBranchDegree(int treeBranchDeg) { - ((ParticleSwarmOptimization)this.m_Optimizer).setTreeBranchDegree(treeBranchDeg); - } - - public String treeBranchDegreeTipText() { - return ((ParticleSwarmOptimization)this.m_Optimizer).treeBranchDegreeTipText(); - } +// /** +// * @return the treeBranchDeg +// */ +// public int getTreeBranchDegree() { +// return ((ParticleSwarmOptimization)this.m_Optimizer).getTreeBranchDegree(); +// } +// +// /** +// * @param treeBranchDeg the treeBranchDeg to set +// */ +// public void setTreeBranchDegree(int treeBranchDeg) { +// ((ParticleSwarmOptimization)this.m_Optimizer).setTreeBranchDegree(treeBranchDeg); +// } +// +// public String treeBranchDegreeTipText() { +// return ((ParticleSwarmOptimization)this.m_Optimizer).treeBranchDegreeTipText(); +// } /** * @return the wrapTopology diff --git a/src/eva2/server/modules/Processor.java b/src/eva2/server/modules/Processor.java index 05f4f58d..da596550 100644 --- a/src/eva2/server/modules/Processor.java +++ b/src/eva2/server/modules/Processor.java @@ -290,12 +290,14 @@ public class Processor extends Thread implements InterfaceProcessor, InterfacePo else if (terminator instanceof EvaluationTerminator) args = new Object[] {optimizer, optimizer.getPopulation(), optimizer.getPopulation().getFunctionCalls(), ((EvaluationTerminator)terminator).getFitnessCalls()}; // ((InterfaceParameterControl)paramCtrl).updateParameters(optimizer, optimizer.getPopulation().getFunctionCalls(), ((EvaluationTerminator)terminator).getFitnessCalls()); - else args = new Object[]{optimizer, optimizer.getPopulation()}; + else args = null;//new Object[]{optimizer, optimizer.getPopulation()}; // ((InterfaceParameterControl)paramCtrl).updateParameters(optimizer); - iterateParamCtrl(optimizer, "updateParameters", args); - args[0]=goParams.getProblem(); - iterateParamCtrl(goParams.getProblem(), "updateParameters", args); + if (args != null) { // only if iteration counting is available + iterateParamCtrl(optimizer, "updateParameters", args); + args[0]=goParams.getProblem(); + iterateParamCtrl(goParams.getProblem(), "updateParameters", args); + } } /** diff --git a/src/eva2/server/stat/AbstractStatistics.java b/src/eva2/server/stat/AbstractStatistics.java index 257429e4..615f0cd8 100644 --- a/src/eva2/server/stat/AbstractStatistics.java +++ b/src/eva2/server/stat/AbstractStatistics.java @@ -13,9 +13,11 @@ import eva2.gui.BeanInspector; import eva2.server.go.IndividualInterface; import eva2.server.go.PopulationInterface; import eva2.server.go.individuals.AbstractEAIndividual; +import eva2.server.go.operators.distancemetric.InterfaceDistanceMetric; import eva2.server.go.populations.Population; import eva2.server.go.problems.InterfaceAdditionalPopulationInformer; import eva2.tools.Mathematics; +import eva2.tools.Pair; /** * An abstract class handling statistics. Most important stuff happens in startOptPerformed, stopOptPerformed @@ -42,7 +44,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter */ private boolean refineMultiRuns = true; private ArrayList meanCollection; - + private Double[] additionalInfoSums = null, lastAdditionalInfoSums=null; // say whether the object should be written to a file every time private boolean saveParams = true; @@ -67,13 +69,15 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter // protected double[] meanBestOfRunFitness; protected double avgPopDist; protected double maxPopDist; - protected IndividualInterface bestCurrentIndividual, bestRunIndividual, bestRunFeasibleIndy, bestFeasibleAllover, bestIndividualAllover; + protected IndividualInterface bestCurrentIndy, bestOfRunIndy, bestOfRunFeasibleIndy, bestFeasibleAllRuns, bestIndyAllRuns; // collect feasible results of a run private ArrayList runBestFeasibleList; private ArrayList runBestFitList; private ArrayList textListeners; + private List lastInformerList = null; + private PopulationInterface lastPop = null; public AbstractStatistics() { firstPlot = true; @@ -99,7 +103,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter * @param infoString */ protected void initOutput(String infoString) { - SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_at_'hh.mm.ss"); + SimpleDateFormat formatter = new SimpleDateFormat("E'_'yyyy.MM.dd'_at_'HH.mm.ss"); String startDate = formatter.format(new Date()); // open the result file: if (doFileOutput() // not "text-window only" @@ -148,22 +152,26 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter convergenceCnt = 0; if (saveParams) m_StatsParams.saveInstance(); initOutput(infoString); - bestIndividualAllover = null; - bestFeasibleAllover = null; + bestIndyAllRuns = null; + bestFeasibleAllRuns = null; // meanBestOfRunFitness = null; // meanBestFeasibleFit = null; runBestFeasibleList = new ArrayList(); runBestFitList = new ArrayList(); if (refineMultiRuns) meanCollection = new ArrayList(); else meanCollection = null; + additionalInfoSums = null; + lastAdditionalInfoSums = null; feasibleFoundAfterSum=-1; numOfRunsFeasibleFound=0; } feasibleFoundAfter=-1; - bestCurrentIndividual = null; - bestRunIndividual = null; + bestCurrentIndy = null; + bestOfRunIndy = null; currentBestFeasibleFit=null; - bestRunFeasibleIndy = null; + bestOfRunFeasibleIndy = null; + lastInformerList = null; + lastPop = null; runIterCnt = 0; if (printRunIntroVerbosity()) printToTextListener("\n****** Multirun "+runNumber); if (params != null) { @@ -187,15 +195,15 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter if (printRunStoppedVerbosity() && (stopMessage != null)) printToTextListener(" Termination message: " + stopMessage + "\n"); if (printRunStoppedVerbosity()) printToTextListener(" Function calls run: " + functionCalls + ", sum: " + functionCallSum + "\n"); // check for convergence - if (bestCurrentIndividual != null) { - if (Mathematics.norm(bestCurrentIndividual.getFitness()) < this.m_StatsParams.getConvergenceRateThreshold()) { + if (bestCurrentIndy != null) { + if (Mathematics.norm(bestCurrentIndy.getFitness()) < this.m_StatsParams.getConvergenceRateThreshold()) { convergenceCnt++; } - if (printRunStoppedVerbosity()) printIndy("Last best", bestCurrentIndividual); + if (printRunStoppedVerbosity()) printIndy("Last best", bestCurrentIndy); } - if (bestRunIndividual != null) { - runBestFitList.add(bestRunIndividual); - if (printRunStoppedVerbosity()) printIndy("Run best", bestRunIndividual); + if (bestOfRunIndy != null) { + runBestFitList.add(bestOfRunIndy); + if (printRunStoppedVerbosity()) printIndy("Run best", bestOfRunIndy); // if (meanBestOfRunFitness==null) { // meanBestOfRunFitness=bestRunIndividual.getFitness().clone(); // } else addSecond(meanBestOfRunFitness, bestRunIndividual.getFitness()); @@ -205,31 +213,46 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } else { if (printRunStoppedVerbosity()) printToTextListener(" NO feasible individual found.\n"); } - if (bestRunFeasibleIndy != null) { - runBestFeasibleList.add(bestRunFeasibleIndy); + if (bestOfRunFeasibleIndy != null) { + runBestFeasibleList.add(bestOfRunFeasibleIndy); // if (meanBestFeasibleFit==null) { // meanBestFeasibleFit=bestRunFeasibleIndy.getFitness().clone(); // } else addSecond(meanBestFeasibleFit, bestRunFeasibleIndy.getFitness()); if (printRunStoppedVerbosity()) { - if ((bestRunFeasibleIndy instanceof AbstractEAIndividual) && ((AbstractEAIndividual)bestRunFeasibleIndy).equalGenotypes((AbstractEAIndividual)bestRunIndividual)) { + if ((bestOfRunFeasibleIndy instanceof AbstractEAIndividual) && ((AbstractEAIndividual)bestOfRunFeasibleIndy).equalGenotypes((AbstractEAIndividual)bestOfRunIndy)) { printToTextListener("* Run best feasible individual equals best individual.\n"); } else { - if (bestRunIndividual instanceof AbstractEAIndividual) { - if (((AbstractEAIndividual)bestRunIndividual).violatesConstraint()) - printToTextListener(" Run best individual violates constraints by " + ((AbstractEAIndividual)bestRunIndividual).getConstraintViolation() + "\n"); - if (((AbstractEAIndividual)bestRunIndividual).isMarkedPenalized()) + if (bestOfRunIndy instanceof AbstractEAIndividual) { + if (((AbstractEAIndividual)bestOfRunIndy).violatesConstraint()) + printToTextListener(" Run best individual violates constraints by " + ((AbstractEAIndividual)bestOfRunIndy).getConstraintViolation() + "\n"); + if (((AbstractEAIndividual)bestOfRunIndy).isMarkedPenalized()) printToTextListener(" Run best individual is penalized.\n"); } - printIndy("Run best feasible", bestRunFeasibleIndy); + printIndy("Run best feasible", bestOfRunFeasibleIndy); } } } + if (printFinalVerbosity()) printToTextListener("."); + if (m_StatsParams.isOutputAdditionalInfo()) updateLastAdditionalInfo(); // if (currentBestFit!= null) { // if (printRunStoppedVerbosity()) printToTextListener(" Best Fitness: " + BeanInspector.toString(currentBestFit) + "\n"); // } - if (optRunsPerformed == m_StatsParams.getMultiRuns()) finalizeOutput(); + if (optRunsPerformed >= m_StatsParams.getMultiRuns()) { + if (printFinalVerbosity()) printToTextListener("\n"); + finalizeOutput(); + } } - + + private PopulationInterface makeStatsPop() { + Population pop = new Population(4); + + if (bestCurrentIndy!=null) pop.add(bestCurrentIndy); + if (bestOfRunIndy!=null) pop.add(bestOfRunIndy); + if (bestOfRunFeasibleIndy!=null) pop.add(bestOfRunFeasibleIndy); + if (bestIndyAllRuns!=null) pop.add(bestIndyAllRuns); + return pop; + } + private void printIndy(String prefix, IndividualInterface indy) { printToTextListener("* " + prefix + " ind.: " + BeanInspector.toString(indy) + '\n'); printToTextListener(" solution data : " + AbstractEAIndividual.getDefaultDataString(indy) + '\n'); @@ -251,7 +274,17 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter printToTextListener(" Average evaluations until feasible ind. was found in " + numOfRunsFeasibleFound + " runs: " + feasibleFoundAfterSum/numOfRunsFeasibleFound + " evaluations\n"); } - if (printFinalVerbosity() && (bestIndividualAllover != null)) printIndy("Overall best", bestIndividualAllover); + if (printFinalVerbosity() && (additionalInfoSums != null)) { + printToTextListener(" Averaged additional info: "); + for (int i=0; i1) { if (runBestFitList.size()>0) { // Mathematics.svDiv((double)optRunsPerformed, meanBestOfRunFitness, meanBestOfRunFitness); @@ -262,7 +295,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter printToTextListener(" MultiRun stats: Median best fitn.: " + BeanInspector.toString(calcMedianFit(runBestFitList))+"\n"); } } - if (printFinalVerbosity() && (bestFeasibleAllover != null)) printIndy("Overall best feasible", bestFeasibleAllover); + if (printFinalVerbosity() && (bestFeasibleAllRuns != null)) printIndy("Overall best feasible", bestFeasibleAllRuns); // if ((runBestFeasibleList.size()>0) && (!equalLists(runBestFeasibleList, runBestFitList))) { // is there a difference between best feasibles and best fit? if (runBestFeasibleList.size()>0) { // always output feasible stats even if theyre equal if (printFinalVerbosity()) { @@ -290,6 +323,15 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } } + private String getFinalAdditionalInfo() { + PopulationInterface bestPop = makeStatsPop(); + StringBuffer sbuf = new StringBuffer("Overall best additional data: "+ getAdditionalInfoHeader(lastInformerList, bestPop)); + sbuf.append('\n'); + appendAdditionalInfo(lastInformerList, bestPop, sbuf); +// getOutputLine(lastInformerList, makeStatsPop()); + return sbuf.toString(); + } + /** * Perform a deep equals test on the fitness vectors of both individual lists. * @param l1 @@ -402,15 +444,21 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter if ((informerList == null) || !m_StatsParams.isOutputAdditionalInfo()) { return headline; } else { - for (InterfaceAdditionalPopulationInformer informer : informerList) { - headline = headline + "\t " + informer.getAdditionalFileStringHeader(pop); - } - return headline; + return headline + getAdditionalInfoHeader(informerList, pop); } } - protected String getOutputLine(List informerList, PopulationInterface pop) { + protected String getAdditionalInfoHeader(List informerList, PopulationInterface pop) { + String hdr=""; + for (InterfaceAdditionalPopulationInformer informer : informerList) { + hdr = hdr + "\t " + informer.getAdditionalFileStringHeader(pop); + } + return hdr; + } + + protected Pair getOutputLine(List informerList, PopulationInterface pop) { StringBuffer sbuf = new StringBuffer(Integer.toString(functionCalls)); + Double[] addNums = null; sbuf.append(" \t "); sbuf.append(BeanInspector.toString(currentBestFit)); if (meanFitness != null) { @@ -421,15 +469,54 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter sbuf.append(" \t "); sbuf.append(BeanInspector.toString(currentWorstFit)); } else sbuf.append(" # \t"); - if (informerList != null && m_StatsParams.isOutputAdditionalInfo()) { - for (InterfaceAdditionalPopulationInformer informer : informerList) { - sbuf.append(" \t "); - sbuf.append(informer.getAdditionalFileStringValue(pop)); - } - } - return sbuf.toString(); + if (m_StatsParams.isOutputAdditionalInfo()) addNums = appendAdditionalInfo(informerList, pop, sbuf); + return new Pair(sbuf.toString(),addNums); } + /** + * Append additional informer informations to the given StringBuffer. + * + * @param informerList + * @param pop + * @param sbuf + */ + protected Double[] appendAdditionalInfo(List informerList, PopulationInterface pop, StringBuffer sbuf) { + if (informerList != null) { + StringBuffer addBuffer = new StringBuffer(); + for (InterfaceAdditionalPopulationInformer informer : informerList) { + addBuffer.append(" \t "); + addBuffer.append(informer.getAdditionalFileStringValue(pop)); + } + String addInfo = addBuffer.toString(); + Double[] retVals = parseDoubles(addInfo, "\t"); + if (sbuf!=null) sbuf.append(addInfo); + return retVals; + } + return null; + } + + /** + * Parse Double from a String separated by the given regular expression. + * For Substrings which do not convert to Double by Double.parseDouble(String), + * a null value is added as representative. + * + * @param str + * @param colSplit + * @return + */ + public static Double[] parseDoubles(String str, String splitRegExp) { + ArrayList vals = new ArrayList(); + String[] entries = str.split(splitRegExp); + for (int i=0; i addInfo = getOutputLine(null, null); + printToTextListener(addInfo.head()+'\n'); + if (addInfo.tail()!=null) { + additionalInfoSums = updateAdditionalInfo(additionalInfoSums, addInfo.tail()); + } + } plotCurrentResults(); runIterCnt++; } + /** + * Add the given array to the member array. Do some checks etc. + * If a resultSum array is provided, it is used to add the info and returned. Otherwise + * a new array is allocated. + * + * @param curInfo + */ + private Double[] updateAdditionalInfo(Double[] resultSum, Double[] curInfo) { + if (resultSum==null) { + resultSum = curInfo.clone(); + } else { + if (curInfo.length != resultSum.length) { + System.err.println("Error in AbstractStatistics.updateAdditionalInfo: mismatching info arrays!"); + } else { + for (int i=0; i informerList) { + lastInformerList = informerList; + lastPop = pop; if (firstPlot) { initPlots(m_StatsParams.getPlotDescriptions()); // if (doTextOutput()) printToTextListener(getOutputHeader(informer, pop)+'\n'); @@ -486,20 +616,20 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter return; } // by default plotting only the best - bestCurrentIndividual = pop.getBestIndividual().getClone(); - if ((bestIndividualAllover == null) || (secondIsBetter(bestIndividualAllover, bestCurrentIndividual))) { - bestIndividualAllover = bestCurrentIndividual; + bestCurrentIndy = pop.getBestIndividual().getClone(); + if ((bestIndyAllRuns == null) || (secondIsBetter(bestIndyAllRuns, bestCurrentIndy))) { + bestIndyAllRuns = bestCurrentIndy; // printToTextListener("new best found!, last was " + BeanInspector.toString(bestIndividualAllover) + "\n"); } - if ((bestRunIndividual==null) || (secondIsBetter(bestRunIndividual, bestCurrentIndividual))) { - bestRunIndividual=bestCurrentIndividual; + if ((bestOfRunIndy==null) || (secondIsBetter(bestOfRunIndy, bestCurrentIndy))) { + bestOfRunIndy=bestCurrentIndy; } // IndividualInterface WorstInd = Pop.getWorstIndividual(); - if (bestCurrentIndividual == null) { + if (bestCurrentIndy == null) { System.err.println("createNextGenerationPerformed BestInd==null"); } - currentBestFit = bestCurrentIndividual.getFitness().clone(); + currentBestFit = bestCurrentIndy.getFitness().clone(); if (currentBestFit == null) { System.err.println("BestFitness==null !"); } @@ -513,12 +643,12 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter feasibleFoundAfterSum+=feasibleFoundAfter; } currentBestFeasibleFit = curBestFeasible.getFitness().clone(); - if ((bestRunFeasibleIndy==null) || (secondIsBetter(bestRunFeasibleIndy, curBestFeasible))) { - bestRunFeasibleIndy=(AbstractEAIndividual)curBestFeasible.clone(); + if ((bestOfRunFeasibleIndy==null) || (secondIsBetter(bestOfRunFeasibleIndy, curBestFeasible))) { + bestOfRunFeasibleIndy=(AbstractEAIndividual)curBestFeasible.clone(); // System.out.println("New best feasible: " + AbstractEAIndividual.getDefaultStringRepresentation((AbstractEAIndividual)bestRunFeasibleIndy)); } - if ((bestFeasibleAllover == null) || (secondIsBetter(bestFeasibleAllover, bestRunFeasibleIndy))) { - bestFeasibleAllover = bestRunFeasibleIndy; + if ((bestFeasibleAllRuns == null) || (secondIsBetter(bestFeasibleAllRuns, bestOfRunFeasibleIndy))) { + bestFeasibleAllRuns = bestOfRunFeasibleIndy; } } } else System.err.println("INVALID POPULATION (AbstractStatistics)"); @@ -528,7 +658,7 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter functionCalls = pop.getFunctionCalls(); if (GraphSelectionEnum.doPlotAvgDist(m_StatsParams.getGraphSelection()) || GraphSelectionEnum.doPlotMaxPopDist(m_StatsParams.getGraphSelection())) { - double[] measures = pop.getPopulationMeasures(); + double[] measures = ((Population)pop).getPopulationMeasures((InterfaceDistanceMetric)null); if (measures != null) { avgPopDist = measures[0]; maxPopDist = measures[2]; @@ -554,12 +684,26 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } // meanCollection.set(pop.getGenerations()-1, means); - if (doTextOutput() && printLineByVerbosity(runIterCnt)) printToTextListener(getOutputLine(informerList, pop)+'\n'); + if (doTextOutput()) { + Pair addInfo = getOutputLine(informerList, pop); + if (printLineByVerbosity(runIterCnt)) printToTextListener(addInfo.head()+'\n'); +// updateAdditionalInfo(addInfo.tail()); + if (addInfo.tail()!=null) { + additionalInfoSums = updateAdditionalInfo(additionalInfoSums, addInfo.tail()); + } + } plotCurrentResults(); runIterCnt++; } + /** + * Returns true if the given iteration is a verbose one according to StatsParameter - meaning + * that full iteration data should be plotted. + * + * @param iteration + * @return + */ private boolean printLineByVerbosity(int iteration) { return (m_StatsParams.getOutputVerbosity().getSelectedTagID() > StatsParameter.VERBOSITY_KTH_IT) || ((m_StatsParams.getOutputVerbosity().getSelectedTagID() == StatsParameter.VERBOSITY_KTH_IT) @@ -567,7 +711,8 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } private boolean printRunIntroVerbosity() { - return (m_StatsParams.getOutputVerbosity().getSelectedTagID() >= StatsParameter.VERBOSITY_KTH_IT); + return (m_StatsParams.getOutputVerbosity().getSelectedTagID() >= StatsParameter.VERBOSITY_KTH_IT) + || (optRunsPerformed==0 && (m_StatsParams.getOutputVerbosity().getSelectedTagID() >= StatsParameter.VERBOSITY_FINAL)); } private boolean printRunStoppedVerbosity() { @@ -622,11 +767,11 @@ public abstract class AbstractStatistics implements InterfaceTextListener, Inter } public IndividualInterface getBestSolution() { - return bestIndividualAllover; + return bestIndyAllRuns; } public IndividualInterface getRunBestSolution() { - return bestRunIndividual; + return bestOfRunIndy; } public int getFitnessCalls() { diff --git a/src/eva2/server/stat/StatisticsStandalone.java b/src/eva2/server/stat/StatisticsStandalone.java index 6f5bdad1..0b9b06b6 100644 --- a/src/eva2/server/stat/StatisticsStandalone.java +++ b/src/eva2/server/stat/StatisticsStandalone.java @@ -60,17 +60,16 @@ public class StatisticsStandalone extends AbstractStatistics implements Interfac } public StatisticsStandalone(String resultFileName) { - this(StatsParameter.getInstance()); - m_StatsParams.SetResultFilePrefix(resultFileName); - m_StatsParams.setOutputTo(m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_FILE)); + this(resultFileName, 1, resultFileName==null ? StatsParameter.VERBOSITY_NONE : StatsParameter.VERBOSITY_FINAL, false); } - public StatisticsStandalone(String resultFileName, int multiRuns, int verbosity) { - this(StatsParameter.getInstance()); + public StatisticsStandalone(String resultFileName, int multiRuns, int verbosity, boolean showAdditionalInfo) { + this(StatsParameter.getInstance(false)); m_StatsParams.setMultiRuns(multiRuns); m_StatsParams.setOutputVerbosity(m_StatsParams.getOutputVerbosity().setSelectedTag(verbosity)); m_StatsParams.SetResultFilePrefix(resultFileName); - m_StatsParams.setOutputTo(m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_FILE)); + if (resultFileName==null) m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_WINDOW); + else m_StatsParams.setOutputTo(m_StatsParams.getOutputTo().setSelectedTag(StatsParameter.OUTPUT_FILE)); } public StatisticsStandalone() { @@ -120,9 +119,9 @@ public class StatisticsStandalone extends AbstractStatistics implements Interfac public void stopOptPerformed(boolean normal, String stopMessage) { super.stopOptPerformed(normal, stopMessage); - if (bestCurrentIndividual != null) { - m_SumOfBestFit = m_SumOfBestFit + bestCurrentIndividual.getFitness()[0]; - m_BestFitnessAtEnd[optRunsPerformed-1] = bestCurrentIndividual.getFitness()[0]; + if (bestCurrentIndy != null) { + m_SumOfBestFit = m_SumOfBestFit + bestCurrentIndy.getFitness()[0]; + m_BestFitnessAtEnd[optRunsPerformed-1] = bestCurrentIndy.getFitness()[0]; } //System.out.println("stopOptPerformed :"+m_OptRunsPerformed); diff --git a/src/eva2/server/stat/StatisticsWithGUI.java b/src/eva2/server/stat/StatisticsWithGUI.java index 2f33ccc4..3f05a8b2 100644 --- a/src/eva2/server/stat/StatisticsWithGUI.java +++ b/src/eva2/server/stat/StatisticsWithGUI.java @@ -86,11 +86,11 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl if ((Client == null) || Client.getHostName().equals(m_MyHostName)) { - m_StatsParams = StatsParameter.getInstance(); + m_StatsParams = StatsParameter.getInstance(true); m_ProxyPrinter = new JTextoutputFrame("TextOutput of " + m_MyHostName); } else { // we use RMI m_StatsParams = (InterfaceStatisticsParameter)RMIProxyLocal.newInstance( - StatsParameter.getInstance()); + StatsParameter.getInstance(true)); m_ProxyPrinter = (JTextoutputFrameInterface) RMIProxyRemote.newInstance(new JTextoutputFrame("TextOutput " + m_MyHostName), m_MainAdapterClient); @@ -246,7 +246,7 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl int subGraph=0; if (doPlotCurrentBest) plotFitnessPoint(0, subGraph++, functionCalls, currentBestFit[0]); - if (doPlotRunBest) plotFitnessPoint(0, subGraph++, functionCalls, bestRunIndividual.getFitness()[0]); + if (doPlotRunBest) plotFitnessPoint(0, subGraph++, functionCalls, bestOfRunIndy.getFitness()[0]); if (doPlotWorst) {// schlechteste Fitness plotten if (currentWorstFit == null) { @@ -261,8 +261,8 @@ public class StatisticsWithGUI extends AbstractStatistics implements Serializabl if (doPlotCurBestFeasible && currentBestFeasibleFit!=null) { plotFitnessPoint(0, subGraph++, functionCalls, currentBestFeasibleFit[0]); } - if (doPlotRunBestFeasible && bestRunFeasibleIndy!=null) { - plotFitnessPoint(0, subGraph++, functionCalls, bestRunFeasibleIndy.getFitness()[0]); + if (doPlotRunBestFeasible && bestOfRunFeasibleIndy!=null) { + plotFitnessPoint(0, subGraph++, functionCalls, bestOfRunFeasibleIndy.getFitness()[0]); } } } diff --git a/src/eva2/server/stat/StatsParameter.java b/src/eva2/server/stat/StatsParameter.java index 2abb93ec..5551b3f9 100644 --- a/src/eva2/server/stat/StatsParameter.java +++ b/src/eva2/server/stat/StatsParameter.java @@ -64,9 +64,17 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl /** * */ - public static StatsParameter getInstance() { + public static StatsParameter getInstance(boolean loadDefaultSerFile) { + if (loadDefaultSerFile) return getInstance("Statistics.ser"); + else return new StatsParameter(); + } + + /** + * Try to load instance from serialized file. If impossible, instantiate a new one. + */ + public static StatsParameter getInstance(String serFileName) { if (TRACE ) System.out.println("Loading serialized stats.."); - StatsParameter Instance = (StatsParameter) Serializer.loadObject("Statistics.ser"); + StatsParameter Instance = (StatsParameter) Serializer.loadObject(serFileName); if (Instance == null) { Instance = new StatsParameter(); if (TRACE) System.out.println("Loading failed!"); @@ -79,7 +87,7 @@ public class StatsParameter implements InterfaceStatisticsParameter, Serializabl */ public StatsParameter() { m_Name = "Statistics"; - outputVerbosity.setSelectedTag(2); + outputVerbosity.setSelectedTag(VERBOSITY_KTH_IT); outputTo.setSelectedTag(1); } diff --git a/src/eva2/tools/Mathematics.java b/src/eva2/tools/Mathematics.java index 222d217b..57ba9e41 100644 --- a/src/eva2/tools/Mathematics.java +++ b/src/eva2/tools/Mathematics.java @@ -36,9 +36,13 @@ public class Mathematics { if (cloneX) in = (double[]) x.clone(); else in = x; - Arrays.sort(in); - if (in.length % 2 != 0) return in[(in.length-1) / 2]; - else return (in[in.length/2] + in[(in.length/2)+1]) / 2.; + if (in.length==1) return in[0]; + else if (in.length==2) return (in[0]+in[1])/2.; + else { + Arrays.sort(in); + if (in.length % 2 != 0) return in[(in.length-1) / 2]; + else return (in[in.length/2] + in[(in.length/2)+1]) / 2.; + } } /** @@ -892,6 +896,24 @@ public class Mathematics { return viols; } + + /** + * Scale a range by the given factor, meaning that the interval in each dimension is + * extended (fact>1) or reduced (fact<1) by the defined ratio around the center. + * + * @param rangeScaleFact + * @param range + */ + public static void scaleRange(double rangeScaleFact, double[][] range) { + double[] intervalLengths=Mathematics.shiftRange(range); + double[] tmpInts=Mathematics.svMult(rangeScaleFact, intervalLengths); + Mathematics.vvSub(tmpInts, intervalLengths, tmpInts); // this is what must be added to range interval + for (int i=0; i> { + boolean useHead = true; + + /** + * A constructor. Set useHd to true to compare based on the head, otherwise + * based on the tail. + */ + public PairComparator(boolean useHd) { + useHead = useHead; + } + + /** + * Compare two Pairs of which head or tail is a primitive type that + * can be converted to double. + * Return 1 if the first is larger, -1 if the second is larger, 0 if they + * are equal or not comparable. + */ + public int compare(Pair o1, Pair o2) { + Pair p1=(Pair)o1; + Pair p2=(Pair)o2; + double d1, d2; + try { + d1=BeanInspector.toDouble(useHead ? p1.head() : p1.tail()); + d2=BeanInspector.toDouble(useHead ? p2.head() : p2.tail()); + } catch (IllegalArgumentException e) { + System.err.println("Error, mismatching types, thus uncomparable Pairs: " + p1.toString() + " / " + p2.toString()); + return 0; + } + + if (d1==d2) return 0; + else if (d1 > d2) return 1; + else return -1; + } +} diff --git a/src/eva2/tools/chart2d/DMeasures.java b/src/eva2/tools/chart2d/DMeasures.java index 037f5a96..a78c8714 100644 --- a/src/eva2/tools/chart2d/DMeasures.java +++ b/src/eva2/tools/chart2d/DMeasures.java @@ -311,6 +311,7 @@ public class DMeasures implements Serializable } } catch( IllegalArgumentException nde ){ return null; } + catch( NullPointerException npe) {return null;} return new SlimRect( x1, y1, x2 - x1, y2 - y1 ); } // SlimRect getSourceOf( double xpos, double ypos, double width, double height){ diff --git a/src/eva2/tools/math/Jama/Matrix.java b/src/eva2/tools/math/Jama/Matrix.java index 9a881d0d..2fc37e5b 100644 --- a/src/eva2/tools/math/Jama/Matrix.java +++ b/src/eva2/tools/math/Jama/Matrix.java @@ -114,16 +114,22 @@ public class Matrix implements Cloneable, java.io.Serializable { */ public Matrix (double[][] A) { - m = A.length; - n = A[0].length; - for (int i = 0; i < m; i++) { - if (A[i].length != n) { - throw new IllegalArgumentException("All rows must have the same length."); - } - } - this.A = A; + this(A, true); } + public Matrix (double[][] A, boolean checkDims) { + m = A.length; + n = A[0].length; + if (checkDims) { + for (int i = 0; i < m; i++) { + if (A[i].length != n) { + throw new IllegalArgumentException("All rows must have the same length."); + } + } + } + this.A = A; + } + /** Construct a matrix quickly without checking arguments. @param A Two-dimensional array of doubles. @param m Number of rows. @@ -660,7 +666,24 @@ public class Matrix implements Cloneable, java.io.Serializable { } return this; } + + /** A = A + B + @param B another matrix + @return A + B + */ + public Matrix plusEqualsArrayAsMatrix(double[][] B) { + if ((B.length!=m) || (B[0].length!=n)) { + throw new IllegalArgumentException("Matrix dimensions must agree."); + } + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = A[i][j] + B[i][j]; + } + } + return this; + } + /** C = A - B @param B another matrix @return A - B @@ -805,6 +828,19 @@ public class Matrix implements Cloneable, java.io.Serializable { return X; } + /** Multiply a matrix in place by a scalar, A = s*A. Returns A. + * @param s scalar + * @return s*A + */ + public Matrix timesInplace(double s) { + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = s*A[i][j]; + } + } + return this; + } + /** Multiply a matrix by a vector, returning A*v. * @param v vector diff --git a/src/eva2/tools/math/RNG.java b/src/eva2/tools/math/RNG.java index 91f5b7ba..80de4e52 100644 --- a/src/eva2/tools/math/RNG.java +++ b/src/eva2/tools/math/RNG.java @@ -8,395 +8,422 @@ import eva2.tools.EVAHELP; import eva2.tools.Mathematics; public class RNG extends Random { - private static Random random; - private static long randomSeed; - /** - * - */ - static { - randomSeed=System.currentTimeMillis(); - random=new Random(randomSeed); - } - /** - * - */ - public static void setRandomSeed(long new_seed){ - //counter++; - randomSeed=new_seed; - if (randomSeed == 0) setRandomSeed(); - else random.setSeed(randomSeed); - } - - /** - * Set the random seed without replacing zero with current system time. - */ - public static void setRandomSeedStrict(long new_seed){ - randomSeed=new_seed; - random.setSeed(randomSeed); - } - /** - * - */ - public static void setRandomSeed() { - randomSeed=System.currentTimeMillis(); - random=new Random(randomSeed); - } - /** - * - */ - public static void setRandom(Random base_random) { - random=base_random; - } - /** - * - */ - public static long getRandomSeed() { - return randomSeed; - } - - /** - * Returns 0 or 1 evenly distributed. - */ - public static int randomInt() { - return randomInt(0,1); - } - - /** - * Returns an evenly distributes int value between zero and - * upperLim-1. - * @param upperLim upper exclusive limit of the random int - */ - public static int randomInt(int upperLim) { - return randomInt(0,upperLim-1); - } - - /** This method returns a evenly distributed int value. - * The boundarys are included. - * @param lo Lower bound. - * @param hi Upper bound. - * @return int - */ - public static int randomInt(int lo,int hi) { - if (hi hi)) { - System.err.println("Error in RNG.randomInt!"); - result = Math.abs(random.nextInt()%(hi-lo+1))+lo; - } - return result; - } - - /** This method returns a random permutation of n int values - * @param length The number of int values - * @return The permutation [0-length-1] - */ - public static int[] randomPermutation(int length) { - boolean[] validList = new boolean[length]; - int[] result = new int[length]; - int index; - for (int i = 0; i < validList.length; i++) validList[i] = true; - for (int i = 0; i < result.length; i++) { - index = randomInt(0, length-1); - while (!validList[index]) { - index++; - if (index == length) index = 0; - } - validList[index] = false; - result[i] = index; - } - return result; - } - - /** This method returns a random permutation of n int values - * @param length The number of int values - * @return The permutation [0-length-1] - */ - public static int[] randomPerm(int length) { - ArrayList intList = new ArrayList(length); - int[] result = new int[length]; - for (int i = 0; i < length; i++) { - intList.add(new Integer(i)); - } - for (int i = 0; i < length-1; i++) { - int index = randomInt(intList.size()); - result[i] = intList.get(index); - intList.remove(index); - - } - if (intList.size()>1) System.err.println("Error in randomPerm!"); - result[length-1] = intList.get(0); - return result; - } - - /** - * - */ - public static long randomLong() { - return randomLong(0,1); - } - /** - * - */ - public static long randomLong(long lo,long hi) { - return (Math.abs(random.nextLong())%(hi-lo+1))+lo; - } - /** - * - */ - public static float randomFloat() { - return random.nextFloat(); - } - /** - * - */ - public static float randomFloat(float lo,float hi) { - return (hi-lo)*random.nextFloat()+lo; - } - /** - * A random double value between 0 and 1. - */ - public static double randomDouble() { - return random.nextDouble(); - } - /** - * - */ - public static double randomDouble(double lo,double hi) { - return (hi-lo)*random.nextDouble()+lo; - } - - /** - * Create a uniform random vector within the given bounds. - */ - public static double[] randomDoubleArray(double[] lo,double[] hi) { - double[] xin = new double[lo.length]; - for (int i=0;i 0, - * - inside a D-Gaussian if nonUnif < 0. - * For case 2, the nonUnif parameter is used as standard deviation (instead of 1/D), the parameter - * is not further used in the other two cases. - * Original code by Maurice Clerc, from the TRIBES package - * - * @param center center point of the distribution - * @param radius radius of the distribution - * @param nonUnif kind of distribution - * - **/ - public static double[] randHypersphere(double[] center, double radius, double nonUnif) { - double[] x = new double[center.length]; - int j; - double xLen, r; - int D=center.length; - -// ----------------------------------- Step 1. Direction - xLen = 0; - for (j=0; j 0) r = Math.pow(r,nonUnif); // non-uniform hypersphere - else r=Math.pow(r,1./D); // Real hypersphere - - for (j=0;j hi)) { + System.err.println("Error, invalid value " + result + " in RNG.randomInt! boundaries were lo/hi: " + lo + " / " + hi); + result = Math.abs(random.nextInt()%(hi-lo+1))+lo; + } + return result; } - return x; - } - - /** - * Adds Gaussian noise to a double vector - * @param v the double vector - * @param dev the Gaussian deviation - */ - public static void addNoise(double[] v, double dev) { - for (int i=0; i intList = new ArrayList(length); + int[] result = new int[length]; + for (int i = 0; i < length; i++) { + intList.add(new Integer(i)); + } + for (int i = 0; i < length-1; i++) { + int index = randomInt(intList.size()); + result[i] = intList.get(index); + intList.remove(index); + + } + if (intList.size()>1) System.err.println("Error in randomPerm!"); + result[length-1] = intList.get(0); + return result; + } + + /** + * Returns a random long between 0 and Long.MAX_VALUE-1 (inclusively). + */ + public static long randomLong() { + return randomLong(0,Long.MAX_VALUE-1); + } + + /** + * Returns a random long between the given values (inclusively). + */ + public static long randomLong(long lo,long hi) { + return (Math.abs(random.nextLong())%(hi-lo+1))+lo; + } + /** + * + */ + public static float randomFloat() { + return random.nextFloat(); + } + /** + * + */ + public static float randomFloat(float lo,float hi) { + return (hi-lo)*random.nextFloat()+lo; + } + /** + * A random double value between 0 and 1. + */ + public static double randomDouble() { + return random.nextDouble(); + } + /** + * + */ + public static double randomDouble(double lo,double hi) { + return (hi-lo)*random.nextDouble()+lo; + } + + /** + * Create a uniform random vector within the given bounds. + */ + public static double[] randomDoubleArray(double[] lo,double[] hi) { + double[] xin = new double[lo.length]; + for (int i=0;i 0, + * - inside a D-Gaussian if nonUnif < 0. + * For case 2, the nonUnif parameter is used as standard deviation (instead of 1/D), the parameter + * is not further used in the other two cases. + * Original code by Maurice Clerc, from the TRIBES package + * + * @param center center point of the distribution + * @param radius radius of the distribution + * @param nonUnif kind of distribution + * + **/ + public static double[] randHypersphere(double[] center, double radius, double nonUnif) { + double[] x = new double[center.length]; + int j; + double xLen, r; + int D=center.length; + +// ----------------------------------- Step 1. Direction + xLen = 0; + for (j=0; j 0) r = Math.pow(r,nonUnif); // non-uniform hypersphere + else r=Math.pow(r,1./D); // Real hypersphere + + for (j=0;j>> (48 - bits)); +// } + // +// public static int testRandomInt(int lo, int hi, long seed) { +// if (hi hi)) { +// System.err.println("Error, invalid value " + result + " in RNG.randomInt! boundaries were lo/hi: " + lo + " / " + hi); +// System.out.println("Error, invalid value " + result + " in RNG.randomInt! boundaries were lo/hi: " + lo + " / " + hi); +// } +// return result; +// } + // +// public static void testRand(long initSeed) { +// for (long seed=initSeed; seed<=Long.MAX_VALUE; seed++) { +// int rnd = testRandomInt(0,8,seed); +// if (seed % 100000000 == 0) System.out.println("Seed at " + seed); +// } +// } + + // public static void main(String[] args) { +// testRand(24000000000l); +// System.out.println("RNG Done"); +// double[] v = new double[2]; +// for (int i=0; i<1000; i++) { +// gaussianVector(1., v, false); +// EVAHELP.logString(Arrays.toString(v)+"\n", "randtest.dat"); +//// System.out.println(Arrays.toString(v)); +// } + // } + + /** + * Create a uniform random double vector within the given bounds (inclusive) in every dimension. + * + * @param n + * @param lower + * @param upper + * @return + */ + // public static double[] randomVector(int n, double lower, double upper) { +// double[] result = new double[n]; +// for (int i = 0; i < result.length; i++) { +// result[i] = RNG.randomDouble(lower, upper); +// } +// return result; + // } + + } \ No newline at end of file diff --git a/src/eva2/tools/tool/BasicResourceLoader.java b/src/eva2/tools/tool/BasicResourceLoader.java index 31db06ed..97fbb7d5 100644 --- a/src/eva2/tools/tool/BasicResourceLoader.java +++ b/src/eva2/tools/tool/BasicResourceLoader.java @@ -256,7 +256,7 @@ public class BasicResourceLoader implements ResourceLoader /** * Fill a line of an array with double values parsed from a String array. A subset of - * Columns may be selected by giving their indeces in an integer array cols. If cols + * Columns may be selected by giving their indices in an integer array cols. If cols * is null, all are converted. * * @param dest @@ -288,7 +288,8 @@ public class BasicResourceLoader implements ResourceLoader } /** - * Test a string for prefixes. If a prefix matches, return its index, else return -1. + * Test a string for prefixes. For the first matching prefix, the index + * of the prefix within the prefix array is returned. If there is no match -1 is returned. * @param str * @param pref * @return @@ -627,23 +628,23 @@ public class BasicResourceLoader implements ResourceLoader if (bytes != null) { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); prop.load(bais); + if (prop != null) return prop; } - if (prop != null) - return prop; ///////////// int slInd = resourceName.lastIndexOf('/'); - if (slInd != -1) - resourceName = resourceName.substring(slInd + 1); + String planBResName; + if (slInd != -1) planBResName = resourceName.substring(slInd + 1); + else planBResName = resourceName; Properties userProps = new Properties(); - File propFile = new File(File.separatorChar + "resources" + File.separatorChar + resourceName); + File propFile = new File(File.separatorChar + "resources" + File.separatorChar + planBResName); if (propFile.exists()) { try { userProps.load(new FileInputStream(propFile)); } catch (Exception ex) { - System.out.println("Problem reading user properties: " + propFile); + System.err.println("Problem reading user properties: " + propFile); } - } + } else System.err.println("Warning in readProperties: neither " + resourceName + " nor " + planBResName + " could be read."); return userProps; } diff --git a/src/eva2/tools/tool/StatisticUtils.java b/src/eva2/tools/tool/StatisticUtils.java index dd87f149..11781905 100644 --- a/src/eva2/tools/tool/StatisticUtils.java +++ b/src/eva2/tools/tool/StatisticUtils.java @@ -14,419 +14,423 @@ package eva2.tools.tool; +import java.util.ArrayList; +import java.util.Collections; + +import eva2.tools.math.Jama.Matrix; /** * Statistic utils. */ public class StatisticUtils { - /** The natural logarithm of 2. */ - public static double log2 = Math.log(2); + /** The natural logarithm of 2. */ + public static double log2 = Math.log(2); - /** The small deviation allowed in double comparisons */ - public static double SMALL = 1e-6; + /** The small deviation allowed in double comparisons */ + public static double SMALL = 1e-6; - /** - * Returns the correlation coefficient of two double vectors. - * - * @param y1 double vector 1 - * @param y2 double vector 2 - * @param n the length of two double vectors - * @return the correlation coefficient - */ - public final static double correlation(double y1[],double y2[],int n) { + /** + * Returns the correlation coefficient of two double vectors. + * + * @param y1 double vector 1 + * @param y2 double vector 2 + * @param n the length of two double vectors + * @return the correlation coefficient + */ + public final static double correlation(double y1[],double y2[],int n) { - int i; - double av1 = 0.0, av2 = 0.0, y11 = 0.0, y22 = 0.0, y12 = 0.0, c; + int i; + double av1 = 0.0, av2 = 0.0, y11 = 0.0, y22 = 0.0, y12 = 0.0, c; - if (n <= 1) { - return 1.0; - } - for (i = 0; i < n; i++) { - av1 += y1[i]; - av2 += y2[i]; - } - av1 /= (double) n; - av2 /= (double) n; - for (i = 0; i < n; i++) { - y11 += (y1[i] - av1) * (y1[i] - av1); - y22 += (y2[i] - av2) * (y2[i] - av2); - y12 += (y1[i] - av1) * (y2[i] - av2); - } - if (y11 * y22 == 0.0) { - c=1.0; - } else { - c = y12 / Math.sqrt(Math.abs(y11 * y22)); - } + if (n <= 1) { + return 1.0; + } + for (i = 0; i < n; i++) { + av1 += y1[i]; + av2 += y2[i]; + } + av1 /= (double) n; + av2 /= (double) n; + for (i = 0; i < n; i++) { + y11 += (y1[i] - av1) * (y1[i] - av1); + y22 += (y2[i] - av2) * (y2[i] - av2); + y12 += (y1[i] - av1) * (y2[i] - av2); + } + if (y11 * y22 == 0.0) { + c=1.0; + } else { + c = y12 / Math.sqrt(Math.abs(y11 * y22)); + } - return c; - } + return c; + } - /** - * Computes differential shannon entropy - * - * @return DSE=SE(AB)-0.5*[SE(A)+SE(B)] - */ - public static double differentialShannon(int counts1[],int counts2[], int n, int countsSum1, int countsSum2) - { - double seA=0.0; - double seB=0.0; - double seAB=0.0; - double c=0.0; - int AB; - int allSum = countsSum1+countsSum2; - for(int i=0;i maximum)) { - maxIndex = i; - maximum = doubles[i]; - } - } + for (int i = 0; i < doubles.length; i++) { + if ((i == 0) || (doubles[i] > maximum)) { + maxIndex = i; + maximum = doubles[i]; + } + } - return maxIndex; - } + return maxIndex; + } - /** - * Returns index of maximum element in a given - * array of integers. First maximum is returned. - * - * @param ints the array of integers - * @return the index of the maximum element - */ - public static int maxIndex(int [] ints) { + /** + * Returns index of maximum element in a given + * array of integers. First maximum is returned. + * + * @param ints the array of integers + * @return the index of the maximum element + */ + public static int maxIndex(int [] ints) { - int maximum = 0; - int maxIndex = 0; + int maximum = 0; + int maxIndex = 0; - for (int i = 0; i < ints.length; i++) { - if ((i == 0) || (ints[i] > maximum)) { - maxIndex = i; - maximum = ints[i]; - } - } + for (int i = 0; i < ints.length; i++) { + if ((i == 0) || (ints[i] > maximum)) { + maxIndex = i; + maximum = ints[i]; + } + } - return maxIndex; - } + return maxIndex; + } - /** - * Returns index of minimum element in a given - * array of integers. First minimum is returned. - * - * @param ints the array of integers - * @return the index of the minimum element - */ - public static int minIndex(int [] ints) { + /** + * Returns index of minimum element in a given + * array of integers. First minimum is returned. + * + * @param ints the array of integers + * @return the index of the minimum element + */ + public static int minIndex(int [] ints) { - int minimum = 0; - int minIndex = 0; + int minimum = 0; + int minIndex = 0; - for (int i = 0; i < ints.length; i++) { - if ((i == 0) || (ints[i] < minimum)) { - minIndex = i; - minimum = ints[i]; - } - } + for (int i = 0; i < ints.length; i++) { + if ((i == 0) || (ints[i] < minimum)) { + minIndex = i; + minimum = ints[i]; + } + } - return minIndex; - } + return minIndex; + } - /** - * Returns index of minimum element in a given - * array of doubles. First minimum is returned. - * - * @param doubles the array of doubles - * @return the index of the minimum element - */ - public static int minIndex(double [] doubles) { + /** + * Returns index of minimum element in a given + * array of doubles. First minimum is returned. + * + * @param doubles the array of doubles + * @return the index of the minimum element + */ + public static int minIndex(double [] doubles) { - double minimum = 0; - int minIndex = 0; + double minimum = 0; + int minIndex = 0; - for (int i = 0; i < doubles.length; i++) { - if ((i == 0) || (doubles[i] < minimum)) { - minIndex = i; - minimum = doubles[i]; - } - } + for (int i = 0; i < doubles.length; i++) { + if ((i == 0) || (doubles[i] < minimum)) { + minIndex = i; + minimum = doubles[i]; + } + } - return minIndex; - } + return minIndex; + } - /** - * Computes the variance for an array of doubles. - * - * @param vector the array - * @return the variance - */ - public static double variance(double[] vector) { + /** + * Computes the variance for an array of doubles. + * + * @param vector the array + * @return the variance + */ + public static double variance(double[] vector) { - double sum = 0, sumSquared = 0; + double sum = 0, sumSquared = 0; - if (vector.length <= 1) { - return 0; - } - for (int i = 0; i < vector.length; i++) { - sum += vector[i]; - sumSquared += (vector[i] * vector[i]); - } - double result = (sumSquared - (sum * sum / (double) vector.length)) / - (double) (vector.length - 1); + if (vector.length <= 1) { + return 0; + } + for (int i = 0; i < vector.length; i++) { + sum += vector[i]; + sumSquared += (vector[i] * vector[i]); + } + double result = (sumSquared - (sum * sum / (double) vector.length)) / + (double) (vector.length - 1); - // We don't like negative variance - if (result < 0) { - return 0; - } else { - return result; - } - } + // We don't like negative variance + if (result < 0) { + return 0; + } else { + return result; + } + } - /** - * Returns c*log2(c) for a given integer value c. - * - * @param c an integer value - * @return c*log2(c) (but is careful to return 0 if c is 0) - */ - public static final double xlogx(int c) { + /** + * Returns c*log2(c) for a given integer value c. + * + * @param c an integer value + * @return c*log2(c) (but is careful to return 0 if c is 0) + */ + public static final double xlogx(int c) { - if (c == 0) { - return 0.0; - } - return c * StatisticUtils.log2((double) c); - } + if (c == 0) { + return 0.0; + } + return c * StatisticUtils.log2((double) c); + } - /** - * Returns c*log2(c) for a given value c. - * - * @param c an integer value - * @return c*log2(c) (but is careful to return 0 if c is 0) - */ - public static final double xlogx(double c) { + /** + * Returns c*log2(c) for a given value c. + * + * @param c an integer value + * @return c*log2(c) (but is careful to return 0 if c is 0) + */ + public static final double xlogx(double c) { - if (c == 0) { - return 0.0; - } - return c * StatisticUtils.log2( c); - } + if (c == 0) { + return 0.0; + } + return c * StatisticUtils.log2( c); + } - /** - * Tests if a is equal to b. - * - * @param a a double - * @param b a double - */ - public static final boolean eq(double a, double b){ + /** + * Tests if a is equal to b. + * + * @param a a double + * @param b a double + */ + public static final boolean eq(double a, double b){ - return (a - b < SMALL) && (b - a < SMALL); - } + return (a - b < SMALL) && (b - a < SMALL); + } - /** - * Tests if a is smaller or equal to b. - * - * @param a a double - * @param b a double - */ - public static final boolean smOrEq(double a,double b) { + /** + * Tests if a is smaller or equal to b. + * + * @param a a double + * @param b a double + */ + public static final boolean smOrEq(double a,double b) { - return (a-b < SMALL); - } + return (a-b < SMALL); + } - /** - * Tests if a is greater or equal to b. - * - * @param a a double - * @param b a double - */ - public static final boolean grOrEq(double a,double b) { + /** + * Tests if a is greater or equal to b. + * + * @param a a double + * @param b a double + */ + public static final boolean grOrEq(double a,double b) { - return (b-a < SMALL); - } + return (b-a < SMALL); + } - /** - * Tests if a is smaller than b. - * - * @param a a double - * @param b a double - */ - public static final boolean sm(double a,double b) { + /** + * Tests if a is smaller than b. + * + * @param a a double + * @param b a double + */ + public static final boolean sm(double a,double b) { - return (b-a > SMALL); - } + return (b-a > SMALL); + } - /** - * Tests if a is greater than b. - * - * @param a a double - * @param b a double - */ - public static final boolean gr(double a,double b) { + /** + * Tests if a is greater than b. + * + * @param a a double + * @param b a double + */ + public static final boolean gr(double a,double b) { - return (a-b > SMALL); - } + return (a-b > SMALL); + } - /** - * returns root mean square error. - */ - public static final double rmsError(double array1[], double array2[]) - { - if ((array1 == null) || (array2 == null)) { return -1.0; } + /** + * returns root mean square error. + */ + public static final double rmsError(double array1[], double array2[]) + { + if ((array1 == null) || (array2 == null)) { return -1.0; } - double errorValueRMS = 0; - for (int i=0; i indices = new ArrayList( samples ); + for( int i=0; i rlhPoints(int samples, int dim, double lb, double ub, boolean edges) + { + ArrayList samplePoints = new ArrayList(samples); + Matrix p = rlh( samples,dim,lb,ub,edges ); + + for( int i=0; i rlhPoints(int samples, double[][] range, boolean edges) + { + ArrayList rlhM = rlhPoints(samples, range.length, 0, 1, edges); + for( int i=0; i