예제 #1
0
        /** Revises the CMA-ES distribution to reflect the current fitness results in the provided subpopulation. */
        public void UpdateDistribution(IEvolutionState state, Subpopulation subpop)
        {
            // % Sort by fitness and compute weighted mean into xmean
            // [arfitness, arindex] = sort(arfitness); % minimization
            // xmean = arx(:,arindex(1:mu))*weights;   % recombination            % Eq.39
            // counteval += lambda;

            // only need partial sort?
            ((List <Individual>)subpop.Individuals).Sort();

            SimpleMatrixD artmp = new SimpleMatrixD(GenomeSize, mu);
            SimpleMatrixD xold  = xmean;

            xmean = new SimpleMatrixD(GenomeSize, 1);

            for (int i = 0; i < mu; i++)
            {
                DoubleVectorIndividual dvind = (DoubleVectorIndividual)subpop.Individuals[i];

                // won't modify the genome
                SimpleMatrixD arz = new SimpleMatrixD(GenomeSize, 1, true, dvind.genome);
                arz = (arz.minus(xold).divide(sigma));

                for (int j = 0; j < GenomeSize; j++)
                {
                    xmean.set(j, 0, xmean.get(j, 0) + weights[i] * dvind.genome[j]);
                    artmp.set(j, i, arz.get(j, 0));
                }
            }

            // % Cumulation: Update evolution paths

            SimpleMatrixD y         = xmean.minus(xold).divide(sigma);
            SimpleMatrixD bz        = invsqrtC.mult(y);
            SimpleMatrixD bz_scaled = bz.scale(Math.Sqrt(cs * (2.0 - cs) * mueff));

            ps = ps.scale(1.0 - cs).plus(bz_scaled);

            double h_sigma_value =
                ((ps.dot(ps) / (1.0 - Math.Pow(1.0 - cs, 2.0 * (state.Generation + 1)))) / GenomeSize);
            int hsig = (h_sigma_value < (2.0 + (4.0 / (GenomeSize + 1)))) ? 1 : 0;

            SimpleMatrixD y_scaled = y.scale(hsig * Math.Sqrt(cc * (2.0 - cc) * mueff));

            pc = pc.scale(1.0 - cc).plus(y_scaled);

            // % Adapt covariance matrix C
            c = c.scale(1.0 - c1 - cmu);
            c = c.plus(pc.mult(pc.transpose()).plus(c.scale((1.0 - hsig) * cc * (2.0 - cc))).scale(c1));
            c = c.plus((artmp.mult(SimpleMatrixD.diag(weights).mult(artmp.transpose()))).scale(cmu));

            // % Adapt step-size sigma
            sigma = sigma * Math.Exp((cs / damps) * (ps.normF() / chiN - 1.0));

            // % Update B and D from C
            if ((state.Generation - lastEigenDecompositionGeneration) > 1.0 / ((c1 + cmu) * GenomeSize * 10.0))
            {
                lastEigenDecompositionGeneration = state.Generation;

                // make sure the matrix is symmetric (it should be already)
                // not sure if this is necessary
                for (int i = 0; i < GenomeSize; i++)
                {
                    for (int j = 0; j < i; j++)
                    {
                        c.set(j, i, c.get(i, j));
                    }
                }

                // this copy gets modified by the decomposition
                DMatrixRMaj copy = c.copy().getMatrix();
                EigenDecomposition <DMatrixRMaj> eig = DecompositionFactory_DDRM.eig(GenomeSize, true, true);
                if (eig.decompose(copy))
                {
                    SimpleMatrixD dinv = new SimpleMatrixD(GenomeSize, GenomeSize);
                    for (int i = 0; i < GenomeSize; i++)
                    {
                        double eigrt = Math.Sqrt(eig.getEigenValue(i).real);
                        d.set(i, i, eigrt);
                        dinv.set(i, i, 1 / eigrt);
                        CommonOps_DDRM.insert(eig.getEigenVector(i), b.getMatrix(), 0, i);
                    }

                    invsqrtC = b.mult(dinv.mult(b.transpose()));
                    CommonOps_DDRM.mult(b.getMatrix(), d.getMatrix(), bd);
                }
                else
                {
                    state.Output.Fatal("CMA-ES eigendecomposition failed. ");
                }
            }

            CommonOps_DDRM.scale(sigma, bd, sbd);

            // % Break, if fitness is good enough or condition exceeds 1e14, better termination methods are advisable
            // if arfitness(1) <= stopfitness || max(D) > 1e7 * min(D)
            //   break;
            // end
            if (useAltTermination && CommonOps_DDRM.elementMax(d.diag().getMatrix()) >
                1e7 * CommonOps_DDRM.elementMin(d.diag().getMatrix()))
            {
                state.Evaluator.SetRunCompleted("CMAESSpecies: Stopped because matrix condition exceeded limit.");
            }
        }