private void testAndCorrectNumerics( CMAEvolutionaryAlgorithm algorithm, int N, List<Individual> individuals) { /* * Flat fitness, Test if funtion values are identical */ /* * we should sort the individuals by fitness value */ Collections.sort(individuals, algorithm.getComparator()); if (algorithm.getGenerations() > 0) { if (individuals.get(0).getFitness() == individuals .get((int) Math.min(algorithm.getLambda() - 1, algorithm.getLambda() / 2.0 + 1) - 1) .getFitness()) { if (debug) { System.err.println( "WARNING - Flat fitness landscape, consider reformulation of fitness," + "step-size increased"); } algorithm.setSigma( algorithm.getSigma() * Math.exp((0.2 + algorithm.getCs() / algorithm.getDamps()))); } } /* * Align (renormalize) scale C and (consequently sigma) */ /* * e.g. for infinite stationary state simulations (noise handling needs to be introduces for * that) */ /* * handling needs to be introduced for that) */ double fac = 1; if (StatUtils.max(algorithm.getDiag()) < 1.0e-6) { fac = 1.0 / StatUtils.max(algorithm.getDiag()); } else if (StatUtils.min(algorithm.getDiag()) > 1.0e+4) { fac = 1.0 / StatUtils.min(algorithm.getDiag()); } if (fac != 1.0) { algorithm.setSigma(algorithm.getSigma() / fac); for (int i = 0; i < N; i++) { algorithm.getPc()[i] *= fac; algorithm.getDiag()[i] *= fac; for (int j = 0; j <= i; j++) { algorithm.getC()[i][j] *= fac * fac; } } } }
@Override public List<Individual> operate(EvolutionaryAlgorithm algorithm, List<Individual> individuals) throws OperatorException { List<Individual> new_population = new ArrayList<Individual>(individuals.size()); CMAEvolutionaryAlgorithm alg = (CMAEvolutionaryAlgorithm) algorithm; debug = algorithm.isDebug(); double[] chromosome; int N = individuals.get(0).getDimension(); countCUpdatesSinceEigenupdate = alg.getCountCupdatesSinceEigenupdate(); // latest possibility to generate B and diagD: eidgendecomposition(alg, N, 0); // ensure minimal and maximal standard deviation: double minsqrtdiagC = Math.sqrt(StatUtils.min(alg.diag(alg.getC()))); double maxsqrtdiagC = Math.sqrt(StatUtils.max(alg.diag(alg.getC()))); /* * TODO: test if it is necessary * */ for (int i = 0; i < individuals.size(); i++) { new_population.add((Individual) individuals.get(i).clone()); } if (lowerStandardDeviation != null && lowerStandardDeviation.length > 0) { for (int i = 0; i < N; i++) { double d = lowerStandardDeviation[Math.min(i, lowerStandardDeviation.length - 1)]; if (d > alg.getSigma() * minsqrtdiagC) { alg.setSigma(d / minsqrtdiagC); } } } if (upperStandardDeviation != null && upperStandardDeviation.length > 0) { for (int i = 0; i < N; i++) { double d = upperStandardDeviation[Math.min(i, upperStandardDeviation.length - 1)]; if (d < alg.getSigma() * maxsqrtdiagC) { alg.setSigma(d / maxsqrtdiagC); } } } testAndCorrectNumerics(alg, N, new_population); double[] artmp = new double[N]; /* * Sample the distribution */ for (int iNk = 0; iNk < alg.getLambda(); iNk++) { chromosome = new_population.get(iNk).getChromosomeAt(0); if (alg.getFlgDiag()) { for (int i = 0; i < N; i++) { chromosome[i] = this.checkBounds( alg, alg.getxMean()[i] + alg.getSigma() * alg.getDiag()[i] * EAFRandom.nextGaussian()); } } else { for (int i = 0; i < N; i++) { artmp[i] = alg.getDiag()[i] * EAFRandom.nextGaussian(); } /* * add mutation (sigma * B * (D*z)) */ for (int i = 0; i < N; i++) { double sum = 0.0; for (int j = 0; j < N; j++) { sum += alg.getB()[i][j] * artmp[j]; } chromosome[i] = this.checkBounds(alg, alg.getxMean()[i] + alg.getSigma() * sum); } } new_population.get(iNk).setChromosomeAt(0, chromosome); } return new_population; }