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); }
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 } } }
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; }
/** 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."); } }
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); } }