예제 #1
0
        public Solution Solve(bool isContinueFromLastSolution = false, bool isOneGenerationOnly = false)
        {
            Solution solution;
            CMAState cmaState;

            if ((!(isContinueFromLastSolution)) || (_solution.Equals(default(Solution))))
            {
                solution = new Solution()
                {
                    StopReason = StopReason.NotSet
                };
                cmaState = new CMAState(_initialCmaParams, new ColumnVector(this.InitialParameters), this.InitialVarianceEstimate);
            }
            else
            {
                solution            = _solution;
                solution.StopReason = StopReason.Restart;
                cmaState            = _solution.LatestCMAState;
            }

            int iteration = 0;

            while ((solution.StopReason == StopReason.NotSet) || (solution.StopReason == StopReason.Restart))
            {
                Solve(iteration++, ref cmaState, ref solution, isOneGenerationOnly);
            }

            _solution = solution;

            return(solution);
        }
예제 #2
0
        private bool IsRestart(ref Solution solution, ColumnVector fitnesses, double tolX, CMAState cmaState)
        {
            bool isAllNaN = fitnesses.All(x => double.IsNaN(x) || double.IsInfinity(x));

            if (isAllNaN)
            {
                return(true);
            }

            // Stop if the condition number of the covariance matrix
            //exceeds 1014 (conditioncov).
            bool isCConditionNumberTooHigh = false;

            if ((Utilities.Diag(cmaState.C, x => x).ToArray().Max() / Utilities.Diag(cmaState.C, x => x).ToArray().Min()) > 1e14)
            {
                isCConditionNumberTooHigh = true;
            }

            if (isCConditionNumberTooHigh)
            {
                return(true);
            }

            if (solution.History == null)
            {
                solution.History = new Queue <double>();
            }

            //Stop if the range of the best objective function values
            //of the last 10 + [30n/lambda] generations is zero
            //(equalfunvalhist), or the range of these function
            //values and all function values of the recent generation
            //is below Tolfun= 10^-12.
            solution.History.Enqueue(fitnesses[0]);
            if (solution.History.Count > (10.0 + ((30.0 * cmaState.p.N) / cmaState.p.Lambda)))
            {
                solution.History.Dequeue();
            }

            bool isObjectiveFunctionRangeTooLow = (solution.History.Count == (int)(10.0 + ((30.0 * cmaState.p.N) / cmaState.p.Lambda))) &&
                                                  ((solution.History.Max() == solution.History.Min()) ||
                                                   (((solution.History.Max() - solution.History.Min()) < ObjectiveFunctionTolerance) && ((fitnesses.Max() - fitnesses.Min()) < ObjectiveFunctionTolerance)));

            if (isObjectiveFunctionRangeTooLow)
            {
                return(true);
            }


            // Stop if the standard deviation of the normal distribution
            //is smaller than TolX in all coordinates and igma]pc
            //(the evolution path from Eq. 2 in [3]) is smaller than
            //TolX in all components. We set TolX= 10^-12*[sigma]^(0).
            bool isStandardDeviationTooSmall = (Utilities.IsTrueForAll(cmaState.C, x => Math.Abs(x) < tolX) && cmaState.ps.All(x => Math.Abs(x) < tolX));

            if (isStandardDeviationTooSmall)
            {
                return(true);
            }

            // Stop if adding a 0.1-standard deviation vector in
            //a principal axis direction of C^(g) does not change
            //<x[vector]>w^(g) (noeffectaxis)3
            int          ith      = (cmaState.gen % cmaState.p.N);
            ColumnVector tmpXmean = (cmaState.mean + 0.1 * cmaState.sigma * cmaState.B * new ColumnVector(cmaState.d));

            bool isNoEffectAxis = false;

            if (ith < tmpXmean.Dimension)
            {
                isNoEffectAxis = (tmpXmean[ith] == cmaState.mean[ith]);
            }

            if (isNoEffectAxis)
            {
                return(true);
            }

            // Stop if adding 0.2-standard deviation in each coordinate
            //does change <x[vector]>w^(g) (noeffectcoord).
            SquareMatrix testC = 0.2 * cmaState.sigma * cmaState.C;
            SquareMatrix vectors;
            SquareMatrix values;

            Utilities.EigAlgLib(testC, out vectors, out values, 1, isGetLower: false);
            ColumnVector colValues = Utilities.Diag(values, x => Math.Sqrt(Math.Abs(x)));

            tmpXmean = (cmaState.mean + cmaState.sigma * vectors * colValues);
            bool isNoEffectCoord = true;

            for (int i = 0; i < cmaState.mean.Dimension; i++)
            {
                if (cmaState.mean[i] != tmpXmean[i])
                {
                    isNoEffectCoord = false;
                    break;
                }
            }

            if (isNoEffectCoord)
            {
                return(true);
            }

            return(false);
        }
예제 #3
0
        private void Solve(int iteration, ref CMAState cmaState, ref Solution solution, bool isOnce = false)
        {
            //ColumnVector xmean = new ColumnVector(parameters);

            double tolX = this.StandardDeviationToleranceMultiple * this.InitialVarianceEstimate;

            int stopeval = this.StopEvals;

            RectangularMatrix arx       = new RectangularMatrix(cmaState.p.N, cmaState.p.Lambda);
            ColumnVector      arfitness = new ColumnVector(cmaState.p.Lambda);

            bool isRestart    = false;
            bool isGoodEnough = false;
            int  counteval    = 0;

            while (counteval < stopeval)
            {
                // Generate and evaluate lambda offspring
                for (int k = 0; k < cmaState.p.Lambda; k++)
                {
                    double[] sample = cmaState.Sample(arx.Column(k));
                    for (int r = 0; r < cmaState.p.N; r++)
                    {
                        arx[r, k] = sample[r];
                    }

                    arfitness[k] = this.ObjectiveFunction(arx.Column(k).ToArray(), this.UserData);

                    counteval++;
                }

                // Sort by fitness and compute weighted mean into xmean
                // minimization
                int[] arindex;
                arfitness = Utilities.Sort(arfitness, out arindex);                 // one based index

                int mu = cmaState.p.Mu;
                cmaState.ReEstimate(
                    (RectangularMatrix)Utilities.GetColumns(arx, arindex.Take(cmaState.p.Mu)),
                    arfitness.First(),
                    arfitness.SkipWhile((f, i) => i < (mu - 1)).First());

                cmaState.UpdateEigenSystem(1, 0);


                if ((solution.StopReason == StopReason.NotSet) || (arfitness[0] < solution.MinimizedFitness))
                {
                    solution.StopReason       = StopReason.Incomplete;
                    solution.MinimizedFitness = arfitness[0];
                    solution.BestCMAState     = cmaState;
                    solution.BestNumEvals     = counteval;
                    solution.BestNumRestarts  = iteration;
                    solution.BestParameters   = cmaState.mean.ToArray();
                }

                if (arfitness[0] <= this.StopFitnessMinimization)
                {
                    isGoodEnough = true;
                    break;
                }

                if (IsRestart(ref solution, arfitness, tolX, cmaState))
                {
                    isRestart = true;
                    break;
                }

                if (isOnce)
                {
                    break;
                }
            }

            if ((isRestart) && (iteration > this.MaxRestarts))
            {
                solution.StopReason = StopReason.MaxRestarts;
            }
            else if ((isRestart) && ((cmaState.p.Lambda * this.RestartPopulationMultiple) > MAX_POPULATIONSIZE))
            {
                solution.StopReason = StopReason.MaxPopulation;
            }
            else if (isRestart)
            {
                solution.History    = new Queue <double>();
                solution.StopReason = StopReason.Restart;
                int previousLambda = cmaState.p.Lambda;
                cmaState = new CMAState(_initialCmaParams, new ColumnVector(this.InitialParameters), this.InitialVarianceEstimate);
                cmaState.p.UpdateLambda((int)(previousLambda * this.RestartPopulationMultiple));
            }
            else if (isGoodEnough)
            {
                solution.StopReason = StopReason.GoodEnough;
            }
            else
            {
                solution.StopReason = StopReason.MaxIterations;
            }

            solution.LatestCMAState    = cmaState;
            solution.LatestNumEvals    = counteval;
            solution.LatestNumRestarts = iteration;
            solution.LatestParameters  = cmaState.mean.ToArray();
        }