private void reset() { if (_featureMap.EliteMap.Count == 0) { _mean = LA.Vector <double> .Build.Dense(_numParams); } else { _mean = DenseVector.OfArray(_featureMap.GetRandomElite().ParamVector); } _direction = LA.Vector <double> .Build.Dense(_featureMap.NumFeatures); for (int i = 0; i < _featureMap.NumFeatures; i++) { _direction[i] = Sampler.gaussian() * _featureMap.GetFeatureScalar(i); } _mutationPower = _params.MutationPower; _pc = LA.Vector <double> .Build.Dense(_numParams); _ps = LA.Vector <double> .Build.Dense(_numParams); _C = new DecompMatrix(_numParams); _individualsEvaluated = 0; }
public DecompMatrix(int numDimensions) { _numDimensions = numDimensions; ConditionNumber = 1.0; C = DenseMatrix.CreateIdentity(_numDimensions); Eigenbasis = DenseMatrix.CreateIdentity(_numDimensions); Eigenvalues = LA.Vector <double> .Build.Dense(_numDimensions, i => 1.0); Invsqrt = DenseMatrix.CreateIdentity(_numDimensions); }
public void Reset() { if (_params.PopulationSize == -1) { _params.PopulationSize = (int)(4.0 + Math.Floor(3.0 * Math.Log(_numParams))); } if (_params.NumParents == -1) { _params.NumParents = _params.PopulationSize / 2; } _mutationPower = _params.MutationPower; _weights = MathNet.Numerics.LinearAlgebra. Vector <double> .Build.Dense(_params.NumParents); for (int i = 0; i < _params.NumParents; i++) { _weights[i] = Math.Log(_params.NumParents + 0.5) - Math.Log(i + 1); } _weights /= _weights.Sum(); double sum_weights = _weights.Sum(); double sum_squares = _weights.Sum(x => x * x); _mueff = sum_weights * sum_weights / sum_squares; _mean = LA.Vector <double> .Build.Dense(_numParams); if (_bestIndividual != null) { for (int i = 0; i < _numParams; i++) { _mean[i] = _bestIndividual.ParamVector[i]; } } Console.WriteLine("RESET"); Console.WriteLine(_mean); _cc = (4 + _mueff / _numParams) / (_numParams + 4 + 2 * _mueff / _numParams); _cs = (_mueff + 2) / (_numParams + _mueff + 5); _c1 = 2 / (Math.Pow(_numParams + 1.3, 2) + _mueff); _cmu = Math.Min(1 - _c1, 2 * (_mueff - 2 + 1 / _mueff) / (Math.Pow(_numParams + 2, 2) + _mueff)); _damps = 1 + 2 * Math.Max(0, Math.Sqrt((_mueff - 1) / (_numParams + 1)) - 1) + _cs; _chiN = Math.Sqrt(_numParams) * (1.0 - 1.0 / (4.0 * _numParams) + 1.0 / (21.0 * Math.Pow(_numParams, 2))); _pc = LA.Vector <double> .Build.Dense(_numParams); _ps = LA.Vector <double> .Build.Dense(_numParams); _C = new DecompMatrix(_numParams); _individualsEvaluated = 0; }
private void reset() { if (_featureMap.EliteMap.Count == 0) { _mean = LA.Vector <double> .Build.Dense(_numParams); } else { _mean = DenseVector.OfArray(_featureMap.GetRandomElite().ParamVector); } _mutationPower = _params.MutationPower; _pc = LA.Vector <double> .Build.Dense(_numParams); _ps = LA.Vector <double> .Build.Dense(_numParams); _C = new DecompMatrix(_numParams); _individualsEvaluated = 0; }
public void UpdateEigensystem() { Evd <double> evd = C.Evd(); Eigenvalues = DenseVector.OfEnumerable(evd.EigenValues.Select(c => c.Real)); Eigenbasis = evd.EigenVectors; for (int i = 0; i < _numDimensions; i++) { for (int j = 0; j <= i; j++) { double sum = 0; for (int k = 0; k < _numDimensions; k++) { sum += Eigenbasis[i, k] * Eigenbasis[j, k] / Math.Sqrt(Eigenvalues[k]); } Invsqrt[i, j] = Invsqrt[j, i] = sum; } } }
public void ReturnEvaluatedIndividual(Individual ind) { bool didAdd = _featureMap.Add(ind); if (ind.Generation != _generation) { return; } if (didAdd) { if (ind.IsNovel) { _novel_parents.Add(ind); } else { _improved_parents.Add(ind); } } _individualsEvaluated++; _population_count++; if (_population_count >= _params.PopulationSize) { int numParents = _novel_parents.Count + _improved_parents.Count; bool needsRestart = numParents == 0; // Only update if we have parents. if (numParents > 0) { var parents = _novel_parents.OrderByDescending(o => o.Delta).Concat( _improved_parents.OrderByDescending(o => o.Delta)).ToList(); // Calculate fresh weights for the number of elites found var weights = LA.Vector <double> .Build.Dense(numParents); for (int i = 0; i < numParents; i++) { weights[i] = Math.Log(numParents + 0.5) - Math.Log(i + 1); } weights /= weights.Sum(); // Dynamically update the hyperparameters for CMA-ES double sumWeights = weights.Sum(); double sumSquares = weights.Sum(x => x * x); double mueff = sumWeights * sumWeights / sumSquares; double cc = (4 + mueff / _numParams) / (_numParams + 4 + 2 * mueff / _numParams); double cs = (mueff + 2) / (_numParams + mueff + 5); double c1 = 2 / (Math.Pow(_numParams + 1.3, 2) + mueff); double cmu = Math.Min(1 - c1, 2 * (mueff - 2 + 1 / mueff) / (Math.Pow(_numParams + 2, 2) + mueff)); double damps = 1 + 2 * Math.Max(0, Math.Sqrt((mueff - 1) / (_numParams + 1)) - 1) + cs; double chiN = Math.Sqrt(_numParams) * (1.0 - 1.0 / (4.0 * _numParams) + 1.0 / (21.0 * Math.Pow(_numParams, 2))); // Recombination of the new mean LA.Vector <double> oldMean = _mean; _mean = LA.Vector <double> .Build.Dense(_numParams); for (int i = 0; i < numParents; i++) { _mean += DenseVector.OfArray(parents[i].ParamVector) * weights[i]; } // Update the evolution path LA.Vector <double> y = _mean - oldMean; LA.Vector <double> z = _C.Invsqrt * y; _ps = (1.0 - cs) * _ps + (Math.Sqrt(cs * (2.0 - cs) * mueff) / _mutationPower) * z; double left = _ps.DotProduct(_ps) / _numParams / (1.0 - Math.Pow(1.0 - cs, 2 * _individualsEvaluated / _params.PopulationSize)); double right = 2.0 + 4.0 / (_numParams + 1.0); double hsig = left < right ? 1 : 0; _pc = (1.0 - cc) * _pc + hsig * Math.Sqrt(cc * (2.0 - cc) * mueff) * y; // Covariance matrix update double c1a = c1 * (1.0 - (1.0 - hsig * hsig) * cc * (2.0 - cc)); _C.C *= (1.0 - c1a - cmu); _C.C += c1 * _pc.OuterProduct(_pc); for (int i = 0; i < _params.NumParents; i++) { LA.Vector <double> dv = DenseVector.OfArray(parents[i].ParamVector) - oldMean; _C.C += weights[i] * cmu *dv.OuterProduct(dv) / (_mutationPower * _mutationPower); } if (checkStop(parents)) { needsRestart = true; } else { _C.UpdateEigensystem(); } // Update sigma double cn = cs / damps; double sumSquarePs = _ps.DotProduct(_ps); _mutationPower *= Math.Exp(Math.Min(1, cn * (sumSquarePs / _numParams - 1) / 2)); } if (needsRestart) { reset(); } _generation++; _individualsDispatched = 0; _population_count = 0; _novel_parents.Clear(); _improved_parents.Clear(); } }
public void ReturnEvaluatedIndividual(Individual ind) { ind.ID = _individualsEvaluatedTotal; _individualsEvaluatedTotal++; if (_bestIndividual == null || _bestIndividual.Fitness < ind.Fitness) { _bestIndividual = ind; } if (ind.Generation != _generation) { return; } // Note that we don't use overflow individuals in adaptation calculations. _individualsEvaluated++; _population.Add(ind); if (_population.Count >= _params.PopulationSize) { // Rank solutions var parents = _population.OrderByDescending(o => o.Fitness) .Take(_params.NumParents).ToList(); Console.WriteLine(parents[0].Fitness); // Recombination of the new mean LA.Vector <double> oldMean = _mean; _mean = LA.Vector <double> .Build.Dense(_numParams); for (int i = 0; i < _params.NumParents; i++) { _mean += DenseVector.OfArray(parents[i].ParamVector) * _weights[i]; } // Update the evolution path LA.Vector <double> y = _mean - oldMean; LA.Vector <double> z = _C.Invsqrt * y; _ps = (1.0 - _cs) * _ps + (Math.Sqrt(_cs * (2.0 - _cs) * _mueff) / _mutationPower) * z; double left = _ps.DotProduct(_ps) / _numParams / (1.0 - Math.Pow(1.0 - _cs, 2 * _individualsEvaluated / _params.PopulationSize)); double right = 2.0 + 4.0 / (_numParams + 1.0); double hsig = left < right ? 1 : 0; _pc = (1.0 - _cc) * _pc + hsig * Math.Sqrt(_cc * (2.0 - _cc) * _mueff) * y; // Covariance matrix update double c1a = _c1 * (1.0 - (1.0 - hsig * hsig) * _cc * (2.0 - _cc)); _C.C *= (1.0 - c1a - _cmu); _C.C += _c1 * _pc.OuterProduct(_pc); for (int i = 0; i < _params.NumParents; i++) { LA.Vector <double> dv = DenseVector.OfArray(parents[i].ParamVector) - oldMean; _C.C += _weights[i] * _cmu *dv.OuterProduct(dv) / (_mutationPower * _mutationPower); } if (CheckStop(parents)) { Reset(); } _C.UpdateEigensystem(); // Update sigma double cn = _cs / _damps; double sumSquarePs = _ps.DotProduct(_ps); _mutationPower *= Math.Exp(Math.Min(1, cn * (sumSquarePs / _numParams - 1) / 2)); _generation++; _individualsDispatched = 0; _population.Clear(); } }