Esempio n. 1
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);
        }