Пример #1
0
        public override void Setup(IEvolutionState state, IParameter paramBase)
        {
            base.Setup(state, paramBase);

            if (!(Species is FloatVectorSpecies))
            {
                state.Output.Error("PSOSubpopulation requires that its Species is ec.vector.FloatVectorSpecies or a subclass.  Yours is: "
                                   + Species.GetType(), null, null);
            }
            if (!(Species.I_Prototype is DoubleVectorIndividual))
            {
                state.Output.Error("PSOSubpopulation requires that its Species' prototypical individual be is ec.vector.DoubleVectorSpecies or a subclass.  Yours is: " + Species.GetType(), null, null);
            }

            NeighborhoodBests   = new DoubleVectorIndividual[Individuals.Count];
            PersonalBests       = new DoubleVectorIndividual[Individuals.Count];
            PreviousIndividuals = new DoubleVectorIndividual[Individuals.Count];

            NeighborhoodSize     = state.Parameters.GetInt(paramBase.Push(P_NEIGHBORHOOD_SIZE), null);
            ClampRange           = state.Parameters.GetBoolean(paramBase.Push(P_CLAMP_RANGE), null, false);
            InitialVelocityScale = state.Parameters.GetDouble(paramBase.Push(P_INITIAL_VELOCITY_SCALE), null, 0);
            VelocityMultiplier   = state.Parameters.GetDouble(paramBase.Push(P_VELOCITY_MULTIPLIER), null, 0.1);

            pFactor = state.Parameters.GetDoubleWithDefault(paramBase.Push(P_P_FACTOR), null, 1);
            nFactor = state.Parameters.GetDoubleWithDefault(paramBase.Push(P_N_FACTOR), null, 1);
            gFactor = state.Parameters.GetDoubleWithDefault(paramBase.Push(P_G_FACTOR), null, 1);
        }
Пример #2
0
        public void DoubleVectorIndividualWriteAndRead()
        {
            // First we'll set up a Fitness for the Individual
            var rand = new MersenneTwisterFast(0);
            var f    = new SimpleFitness();

            f.SetFitness(null, float.MaxValue, true);

            const int n = 10;

            f.Trials = new List <double>(n);
            for (var i = 0; i < n; i++)
            {
                f.Trials.Add(rand.NextDouble());
            }

            // Now we can create and initialize the Individual
            var ind  = new DoubleVectorIndividual();
            var ind2 = new DoubleVectorIndividual(); // We'll read back into this instance

            ind.Genome = new double[10];             // This is the set of genes
            for (var i = 0; i < 10; i++)
            {
                ind.genome[i] = rand.NextDouble() * double.MaxValue; // some random genes
            }
            ind.Fitness   = f;
            ind.Evaluated = true;

            using (var ms = new MemoryStream())
            {
                var writer = new BinaryWriter(ms);
                ind.WriteIndividual(null, writer);

                ms.Position = 0;
                var reader = new BinaryReader(ms);

                ind2.Fitness = new SimpleFitness();
                ind2.ReadIndividual(null, reader);

                Assert.IsTrue(ind.Fitness.EquivalentTo(ind2.Fitness));
                Assert.IsTrue(ind2.Fitness.IsIdeal);
                Assert.IsTrue(ind.Equals(ind2)); // Genetically equivalent
                for (var i = 0; i < 10; i++)
                {
                    Assert.AreEqual(ind.genome[i], ind2.genome[i]); // check each gene
                }
            }
        }
Пример #3
0
        public void Evaluate(IEvolutionState state, Individual ind, int subpopulation, int threadnum)
        {
            if (ind.Evaluated)
            {
                return;
            }

            DoubleVectorIndividual _ind = (DoubleVectorIndividual)ind;
            int vertexSkip = NumVertices * 2 + 4; // for four colors

            pic.Clear();
            for (int i = 0; i < _ind.genome.Length; i += vertexSkip)
            {
                pic.AddPolygon(_ind.genome, i, NumVertices);
            }

            double error = pic.Error();

            ((SimpleFitness)_ind.Fitness).SetFitness(state, (float)(1.0 - error), error == 0);
            ind.Evaluated = true;
        }
Пример #4
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.");
            }
        }
Пример #5
0
        public override Individual NewIndividual(IEvolutionState state, int thread)
        {
            Individual       newind = base.NewIndividual(state, thread);
            IMersenneTwister random = state.Random[thread];

            if (!(newind is DoubleVectorIndividual)) // uh oh
            {
                state.Output.Fatal(
                    "To use CMAESSpecies, the species must be initialized with a DoubleVectorIndividual.  But it contains a " +
                    newind);
            }

            DoubleVectorIndividual dvind = (DoubleVectorIndividual)(newind);

            DMatrixRMaj genome = DMatrixRMaj.wrap(GenomeSize, 1, dvind.genome);
            DMatrixRMaj temp   = new DMatrixRMaj(GenomeSize, 1);

            // arz(:,k) = randn(N,1); % standard normally distributed vector
            // arx(:,k) = xmean + sigma*(B*D*arz(:,k));
            int tries = 0;

            while (true)
            {
                for (int i = 0; i < GenomeSize; i++)
                {
                    dvind.genome[i] = random.NextGaussian();
                }

                CommonOps_DDRM.mult(sbd, genome, temp);              // temp = sigma*b*d*genome;
                CommonOps_DDRM.add(temp, xmean.getMatrix(), genome); // genome = temp + xmean;

                bool invalid_value = false;
                for (int i = 0; i < GenomeSize; i++)
                {
                    if (dvind.genome[i] < MinGenes[i] || dvind.genome[i] > MaxGenes[i])
                    {
                        if (useAltGenerator && tries > altGeneratorTries)
                        {
                            // instead of just failing, we're going to select uniformly from
                            // possible values for this particular gene.
                            dvind.genome[i] = state.Random[thread].NextDouble() * (MaxGenes[i] - MinGenes[i]) +
                                              MinGenes[i];
                        }
                        else
                        {
                            invalid_value = true;
                            break;
                        }
                    }
                }

                if (invalid_value)
                {
                    if (++tries > MAX_TRIES_BEFORE_WARNING)
                    {
                        state.Output.WarnOnce(
                            "CMA-ES may be slow because many individuals are being generated which\n" +
                            "are outside the min/max gene bounds.  If an individual violates a single\n" +
                            "gene bounds, it is rejected, so as the number of genes grows, the\n" +
                            "probability of this happens increases exponentially.  You can deal\n" +
                            "with this by decreasing sigma.  Alternatively you can use set\n" +
                            "pop.subpop.0.alternative-generation=true (see the manual).\n" +
                            "Finally, if this is happening during initialization, you might also\n" +
                            "change pop.subpop.0.species.covariance=scaled.\n");
                    }
                    continue;
                }

                return(newind);
            }
        }