コード例 #1
0
        protected override double run(out double[] xStar)
        {
            /* this is just to overcome a small issue with the compiler. It thinks that xStar will
             * not have a value since it only appears in a conditional statement below. This initi-
             * alization is to "ensure" that it does and that the code compiles. */
            xStar = null;
            //evaluate f(x0)
            fStar = fk = calc_f(x);
            do
            {
                gradF = calc_f_gradient(x);
                var step = gradF.norm2();
                dk = searchDirMethod.find(x, gradF, fk, ref alphaStar);
                // use line search (arithmetic mean) to find alphaStar
                alphaStar = lineSearchMethod.findAlphaStar(x, dk, step);
                x         = x.add(StarMath.multiply(alphaStar, dk));
                SearchIO.output("iteration=" + k, 3);
                k++;
                fk = calc_f(x);
                if (fk < fStar)
                {
                    fStar = fk;
                    xStar = (double[])x.Clone();
                }
                SearchIO.output("f = " + fk, 3);
            } while (notConverged(k, numEvals, fk, x, null, gradF));

            return(fStar);
        }
コード例 #2
0
        /// <summary>
        /// Given a minimum span, S, this criteria returns true when the span is equal to
        /// or less than S. This is probably the slowest criteria (p*log(p)) given that it must
        /// check the distance between every pair of solutions in the population. But, probably
        /// not an significant increase  for p less than 1000.
        /// </summary>
        /// <param name="iteration">The number of iterations (not used).</param>
        /// <param name="numFnEvals">The number of function evaluations (not used).</param>
        /// <param name="fBest">The best f (not used).</param>
        /// <param name="xBest">The best x (not used).</param>
        /// <param name="population">The population of candidates.</param>
        /// <param name="gradF">The gradient of F (not used).</param>
        /// <returns>
        /// true or false - has the process converged?
        /// </returns>
        public override bool converged(long iteration = -1, long numFnEvals = -1, double fBest = double.NaN, IList <double> xBest = null, IList <double[]> population = null, IList <double> gradF = null)
        {
            if (population == null)
            {
                throw new Exception("MaxSpanInPopulationConvergence expected an array of arrays of doubles (in the last argument, YJaggedDoubleArray) "
                                    + " representing the current simplex of solutions.");
            }
            if (population.Count == 0)
            {
                return(false);
            }
            double maxSideLength = 0;
            double minSideLength = double.PositiveInfinity;

            for (var i = 0; i < population.Count - 1; i++)
            {
                for (var j = i + 1; j < population.Count; j++)
                {
                    var sideLengthSquared = population[i].norm2(population[j], true);
                    if (maxSideLength < sideLengthSquared)
                    {
                        maxSideLength = sideLengthSquared;
                    }
                    if (minSideLength > sideLengthSquared)
                    {
                        minSideLength = sideLengthSquared;
                    }
                }
            }
            SearchIO.output("ratio =" + Math.Sqrt(minSideLength / maxSideLength), 5);
            SearchIO.output("side length =" + Math.Sqrt(maxSideLength), 5);
            return(Math.Sqrt(maxSideLength) <= MinimumSpan);
        }
コード例 #3
0
        /// <summary>
        /// Runs the specified x star.
        /// </summary>
        /// <param name="xStar">The x star.</param>
        /// <returns>System.Double.</returns>
        protected override double run(out double[] xStar)
        {
            var candidates = new List <ICandidate> {
                new Candidate(calc_f(x), x)
            };
            var temperature = scheduler.SetInitialTemperature();

            while (notConverged(k++, numEvals, candidates[0].objectives[0], candidates[0].x))
            {
                SearchIO.output(k + ": f = " + candidates[0].objectives[0], 4);
                SearchIO.output("     x = " + candidates[0].x.MakePrintString(), 4);
                var neighbors = neighborGenerator.GenerateCandidates(candidates[0].x);
                var feasibleAndEvaluatedNeighbors =
                    from neighbor in neighbors
                    where ConstraintsSolvedWithPenalties || feasible(neighbor)
                    let f = calc_f(neighbor)
                            select new Candidate(f, neighbor);
                candidates.AddRange(feasibleAndEvaluatedNeighbors.Cast <ICandidate>());

                temperature = scheduler.UpdateTemperature(temperature, candidates);
                SearchIO.output("temperture = " + temperature, 3);
                selector.SelectCandidates(ref candidates, control: temperature);
            }
            xStar = candidates[0].x;
            return(candidates[0].objectives[0]);
        }
コード例 #4
0
        /// <summary>
        /// Open the problem definition from XML.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns>ProblemDefinition.</returns>
        public static ProblemDefinition OpenprobFromXml(Stream stream)
        {
            var    probReader       = new StreamReader(stream);
            var    probDeserializer = new XmlSerializer(typeof(ProblemDefinition));
            var    newDesignprob    = (ProblemDefinition)probDeserializer.Deserialize(probReader);
            string name             = getNameFromStream(stream);

            SearchIO.output(name + " successfully loaded.");
            if (newDesignprob.name == null)
            {
                newDesignprob.name = name;
            }
            foreach (var item in newDesignprob.FunctionList.Items)
            {
                if (item is IObjectiveFunction)
                {
                    newDesignprob.f.Add((IObjectiveFunction)item);
                }
                else if (item is IInequality)
                {
                    newDesignprob.g.Add((IInequality)item);
                }
                else if (item is IEquality)
                {
                    newDesignprob.h.Add((IEquality)item);
                }
            }
            newDesignprob.FunctionList = new ListforIOptFunctions(newDesignprob.f, newDesignprob.g, newDesignprob.h);
            probReader.Dispose();
            return(newDesignprob);
        }
コード例 #5
0
        public override void SelectCandidates(ref List <ICandidate> candidates, double temperature = double.NaN)
        {
            var fOld = candidates[0].objectives[0];
            var fNew = candidates[1].objectives[0];

            if ((fNew == fOld) || (BetterThan(fNew, fOld)))
            {
                /* throw away the old and keep the new */
                candidates.RemoveAt(0);
            }
            else
            {
                var probability = Math.Exp(((int)optDirections[0]) * (fNew - fOld) / temperature);
                SearchIO.output("fnew = " + fNew + "; fold = " + fOld + "; prob = " + probability, 5);
                if (rnd.NextDouble() <= probability)
                {
                    /* throw away the old and keep the new */
                    candidates.RemoveAt(0);
                    SearchIO.output("keep new", 5);
                }
                /* otherwise stay with the old */
                else
                {
                    candidates.RemoveAt(1);
                    SearchIO.output("keep old", 5);
                }
            }
        }
コード例 #6
0
ファイル: PatternSearch.cs プロジェクト: mdecourse/OOOT
        protected override double run(out double[] xStar)
        {
            var xCopy       = x;
            var meshSize    = max - min;
            var iterations  = 0;
            var stepsize    = 10.0;
            var alpha       = 2.0;
            var GlobalXstar = new double[n];

            while (iterations < 5)
            {
                iterations++;
                SomeFunctions.MyClass trialneighbors = new SomeFunctions.MyClass();
                var    neighbors     = trialneighbors.generateNeighbors(xCopy, meshSize, stepsize);
                double minFstar_orig = calc_f(xCopy);
                double minFstar      = minFstar_orig;
                int    indexVal      = 0;
                for (int i = 0; i < neighbors.Count; i++)
                {
                    var fstar = calc_f(neighbors [i]);
                    if (fstar <= minFstar)
                    {
                        minFstar = fstar;
                        indexVal = i;
                        SearchIO.output("better obtained: " + fstar);
                    }
                }

                SearchIO.output("iterations:" + iterations);
                if (minFstar < minFstar_orig)
                {
                    var xCopy1 = neighbors [indexVal];
                    var xCopy2 = StarMath.add(xCopy1, StarMath.multiply(alpha, StarMath.subtract(xCopy1, xCopy)));
                    var fStar  = calc_f(xCopy2);
                    if (fStar <= minFstar)
                    {
                        xCopy2.CopyTo(xCopy, 0);
                        xCopy2.CopyTo(GlobalXstar, 0);
                    }
                    else
                    {
                        xCopy1.CopyTo(xCopy, 0);
                        xCopy1.CopyTo(GlobalXstar, 0);
                    }
                    meshSize = meshSize * 2;
                }
                else
                {
                    meshSize = meshSize / 2;
                    stepsize = stepsize * 0.9;
                }
            }

            xStar = new double[8];
            xStar = GlobalXstar;
            return(calc_f(xStar));
        }
コード例 #7
0
ファイル: ExhaustiveSearch.cs プロジェクト: mdecourse/OOOT
        private void performTimePrediction(DateTime startTime)
        {
            double span = (DateTime.Now - startTime).Ticks;

            span /= timePreditionIndex;
            span *= spaceDescription.SizeOfSpace;
            var endTime = startTime + new TimeSpan((long)span);

            SearchIO.output("Predicted time for the process to end:\n" + endTime);
        }
コード例 #8
0
ファイル: NewtonMethod.cs プロジェクト: DesignEngrLab/OOOT
        /// <summary>
        /// Runs the specified x star.
        /// </summary>
        /// <param name="xStar">The x star.</param>
        /// <returns>System.Double.</returns>
        /// <exception cref="Exception">Newton's method requires that the objective function be twice differentiable"
        ///                 + "\n(Must inherit from ITwiceDifferentiable).</exception>
        protected override double run(out double[] xStar)
        {
            if (!(f[0] is ITwiceDifferentiable))
            {
                throw new Exception("Newton's method requires that the objective function be twice differentiable"
                                    + "\n(Must inherit from ITwiceDifferentiable).");
            }

            /* this is just to overcome a small issue with the compiler. It thinks that xStar will
             * not have a value since it only appears in a conditional statement below. This initi-
             * alization is to "ensure" that it does and that the code compiles. */
            xStar = (double[])x.Clone();
            //evaluate f(x0)
            fStar = fk = calc_f(x);
            do
            {
                gradF = calc_f_gradient(x);
                var Hessian = new double[n, n];
                for (int i = 0; i < n; i++)
                {
                    for (int j = i; j < n; j++)
                    {
                        Hessian[i, j] = Hessian[j, i] = ((ITwiceDifferentiable)f[0]).second_deriv_wrt_ij(x, i, j);
                    }
                }

                dk = StarMath.multiply(-1, Hessian.inverse().multiply(gradF));
                if (double.IsNaN(dk.SumAllElements()))
                {
                    dk = StarMath.multiply(-1, gradF);
                }
                var step = dk.norm2();
                if (step == 0)
                {
                    continue;
                }
                dk = dk.divide(step);
                // use line search (arithmetic mean) to find alphaStar
                alphaStar = lineSearchMethod.findAlphaStar(x, dk, step);
                x         = x.add(StarMath.multiply(alphaStar, dk));
                SearchIO.output("iteration=" + k, 3);
                k++;
                fk = calc_f(x);
                if (fk < fStar)
                {
                    fStar = fk;
                    xStar = (double[])x.Clone();
                }
                SearchIO.output("f = " + fk, 3);
            } while (notConverged(k, numEvals, fk, x, null, gradF));

            return(fStar);
        }
コード例 #9
0
        /// <summary>
        /// Performs the time prediction.
        /// </summary>
        /// <param name="startTime">The start time.</param>
        private void performTimePrediction(DateTime startTime)
        {
            double span = (DateTime.Now - startTime).Ticks;

            span /= timePreditionIndex;
            span *= spaceDescription.SizeOfSpace;
            var endTime = startTime + new TimeSpan((long)span);

            SearchIO.output(timePreditionIndex + " states evaluated. " + spaceDescription.SizeOfSpace +
                            " total states (" + 100 * timePreditionIndex / spaceDescription.SizeOfSpace
                            + "% complete)");
            SearchIO.output("Predicted time for the process to end:\n" + endTime);
        }
コード例 #10
0
 /// <summary>
 /// Runs the optimization process and returns the optimal as xStar
 /// and the value of fStar is return by the function.
 /// </summary>
 /// <param name="xStar">The optimizer, xStar.</param>
 /// <returns>optimal value, fStar</returns>
 public double Run(out double[] xStar)
 {
     if (xStart != null)
     {
         return(Run(out xStar, xStart));
     }
     if (((spaceDescriptor != null) && (spaceDescriptor.Count > 0)) || (n > 0))
     {
         return(run(out xStar, null));
     }
     SearchIO.output("The number of variables was not set or determined from inputs.", 0);
     xStar = null;
     return(double.PositiveInfinity);
 }
コード例 #11
0
        /// <summary>
        /// Runs the specified optimization method. This includes the details
        /// of the optimization method.
        /// </summary>
        /// <param name="xStar">The x star.</param>
        /// <returns>System.Double.</returns>
        protected override double run(out double[] xStar)
        {
            //evaluate f(x0)
            fStar = fk = calc_f(x);
            dk    = new double[n];

            /* this is the iteration counter for updating Xc it's compared with feasibleOuterLoopMax. */
            foreach (var c in h)
            {
                active.Add(c);
            }
            /* this forces formulateActiveSetAndGradients to do the division. */
            divideX = true;

            do
            {
                gradF = calc_f_gradient(x);
                formulateActiveSetAndGradients(x, divideX);
                calculateReducedGradientSearchDirection();

                /* whether or not the previous two lines of code reformulated Xc and Xd, we now
                 * set it to false so that it won't do so next iteration. However, there are two
                 * places in which this might change. First, if the update for Xc requires a lot of
                 * effort and the alphaStar needs to be reduced; and Second, in formulateActive... if
                 * there are new violated constraints or an old constraint is no longer infeasible. */
                divideX = false;

                /* use line search (e.g. arithmetic mean) to find alphaStar */
                alphaStar = lineSearchMethod.findAlphaStar(x, dk);

                xkLast = x;
                x      = xkLast.add(StarMath.multiply(alphaStar, dk));
                int outerFeasibleK = 0;
                while (!updateXc() && (++outerFeasibleK <= feasibleOuterLoopMax))
                {
                    alphaStar /= 2;
                    x          = xkLast.add(StarMath.multiply(alphaStar, dk));
                    divideX    = true;
                }
                k++;
                fk = calc_f(x);

                SearchIO.output("x(" + k + ") = " + x.MakePrintString() + " = " + fk.ToString("0.00"), 4);
            } while (notConverged(k, numEvals, fk, x, null, gradF));

            fStar = fk;
            xStar = x;
            return(fStar);
        }
コード例 #12
0
        protected override double run(out double[] xStar)
        {
            fStar = calc_f(x);
            var xBase = x;
            var fBase = fStar;

            if (!explore(out stepSize))
            {
                xStar = xBase;
                return(fBase);
            }
            var xAfterExplore = x;
            var fAfterExplore = fStar = calc_f(x);

            while (notConverged(k++, numEvals, fStar, x))
            {
                SearchIO.output("iter=" + k, 2);
                var xProject = x = xAfterExplore.add(xAfterExplore.subtract(xBase).multiply(alpha));
                fStar    = calc_f(x);
                stepSize = Math.Max(stepSize, xProject.subtract(xAfterExplore).norm2());
                double nextStepSize;
                if (explore(out nextStepSize) && fStar < fAfterExplore)
                {
                    xBase         = xProject;
                    xAfterExplore = x;
                    fAfterExplore = fStar;
                    stepSize      = nextStepSize;
                }
                else
                {
                    SearchIO.output("explore failed", 5);
                    x     = xAfterExplore;
                    fStar = fAfterExplore;
                    if (explore(out nextStepSize))
                    {
                        xBase         = xAfterExplore;
                        xAfterExplore = x;
                        fAfterExplore = fStar;
                        stepSize      = nextStepSize;
                    }
                    else
                    {
                        stepTooSmallConvergence.hasConverged = true;
                    }
                }
            }
            xStar = x;
            return(fStar);
        }
コード例 #13
0
 /// <summary>
 /// Adds an element with the provided key and value to the <see cref="T:System.Collections.Generic.IDictionary`2" />.
 /// </summary>
 /// <param name="key">The object to use as the key of the element to add.</param>
 /// <param name="value">The object to use as the value of the element to add.</param>
 /// <exception cref="T:System.ArgumentNullException"><paramref name="key" /> is null.</exception>
 /// <exception cref="T:System.ArgumentException">An element with the same key already exists in the <see cref="T:System.Collections.Generic.IDictionary`2" />.</exception>
 /// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IDictionary`2" /> is read-only.</exception>
 public void Add(double[] key, double value)
 {
     if (Parameters.MaxFunctionDataStore == 0)
     {
         return;
     }
     oldEvaluations.Add(key, value);
     if (queue.Count >= Parameters.MaxFunctionDataStore)
     {
         SearchIO.output("reducing queue...", 4);
         for (int i = 0; i < Parameters.FunctionStoreCleanOutStepDown; i++)
         {
             Remove(queue.Dequeue());
         }
     }
     queue.Enqueue(key);
 }
コード例 #14
0
        /// <summary>
        /// Runs the specified optimization method. This includes the details
        /// of the optimization method.
        /// </summary>
        /// <param name="xStar">The x star.</param>
        /// <returns>System.Double.</returns>
        protected override double run(out double[] xStar)
        {
            var population = new List <ICandidate>();

            /* 1. make initial population and evaluate
             *    to ensure diversity, a latin hyper cube with Hammersley could be used.*/
            SearchIO.output("creating initial population", 4);
            initGenerator.GenerateCandidates(ref population, control: populationSize);
            SearchIO.output("evaluating initial population", 4);
            evaluate(population);

            do
            {
                SearchIO.output("", "", k, "iter = " + k,
                                "*******************\n* Iteration: " + k + " *\n*******************");
                /* 3. selection survivors*/
                SearchIO.output("selecting from population  (current pop = " + population.Count + ").", 4);
                SearchIO.output(CalcPopulationStats(population).MakePrintString(), 4);
                fitnessSelector.SelectCandidates(ref population);
                /* 4. generate remainder of population with crossover generators */
                SearchIO.output("generating new candidates (current pop = " + population.Count + ").", 4);
                if (crossoverGenerator != null)
                {
                    crossoverGenerator.GenerateCandidates(ref population, control: populationSize);
                }
                /* 5. generate modifications to all with mutation */
                SearchIO.output("performing mutation (current pop = " + population.Count + ").", 4);
                if (mutationGenerator != null)
                {
                    mutationGenerator.GenerateCandidates(ref population);
                }
                /* 6. evaluate new members of population.*/
                SearchIO.output("evaluating new popluation members.", 4);
                evaluate(population);
                k++;
                fStar = population.Min(c => c.objectives[0]);
                xStar = (from candidate in population
                         where (candidate.objectives[0] == fStar)
                         select candidate.x).First();
                SearchIO.output("x* = " + xStar.MakePrintString(), 4);
                SearchIO.output("f* = " + fStar, 4);
            } while (notConverged(k, numEvals, fStar, xStar, population.Select(a => a.x).ToList(),
                                  population.Select(a => a.objectives[0]).ToList()));
            return(fStar);
        }
コード例 #15
0
        protected override double run(out double[] xStar)
        {
            fStar = fk = calc_f(x);

            /* this is the iteration counter for updating Xc it's compared with feasibleOuterLoopMax. */
            foreach (IEquality c in h)
            {
                active.Add(c);
            }
            divideXintoDecisionAndDependentVars();

            do
            {
                gradH = calc_h_gradient(x);
                divideGradH_intoXcAndXdParts();
                invGradHWRT_xc = gradHWRT_xc.inverse(); //should this just be inverseUpper?
                gradF          = calc_f_gradient(x);
                calculateReducedGradientSearchDirection();

                // use line search (arithmetic mean) to find alphaStar
                lineSearchMethod.lastFeasAlpha4G = 0.0;
                lineSearchMethod.findAlphaStar(x, dk);
                alphaStar = lineSearchMethod.lastFeasAlpha4G;
                //alphaStar = lineSearchMethod.findAlphaStar(xk, dk, g);

                xkLast = x;
                x      = xkLast.add(StarMath.multiply(alphaStar, dk));
                var outerFeasibleK = 0;
                while (!updateXc() && (++outerFeasibleK == feasibleOuterLoopMax))
                {
                    alphaStar /= 2;
                    x          = xkLast.add(StarMath.multiply(alphaStar, dk));
                }
                k++;
                fk = calc_f(x);
                SearchIO.output("X = " + x[0] + ", " + x[1], 3); // + ", " + xk[2]
                SearchIO.output("F(" + k + ") = " + fk, 3);
            } while (notConverged(k, numEvals, fk, x, null, gradF));
            fStar = fk;
            xStar = x;
            SearchIO.output("X* = " + x[0] + ", " + x[1], 2);
            SearchIO.output("F* = " + fk, 2);
            return(fStar);
        }
コード例 #16
0
        /// <summary>
        /// Determines the pfrom q.
        /// </summary>
        private void determinePfromQ()
        {
            if (q <= minQ)
            {
                p = 0.0;
            }
            else if (q >= maxQ)
            {
                p = (double)optDirections[0] * maxP;
            }
            else
            {
                p = (double)optDirections[0] * (minP + (maxP - minP) * Math.Pow(q, v));
            }


            SearchIO.output("", "", "", "q=" + q + ",p=" + p,
                            "q = " + q + " changed to p = " + p);
        }
コード例 #17
0
        /// <summary>
        /// Determines the qfrom p.
        /// </summary>
        private void determineQfromP()
        {
            if (Math.Abs(p) <= minP)
            {
                q = minQ;
            }
            else if (Math.Abs(p) >= maxP)
            {
                q = maxQ;
            }
            else
            {
                q = Math.Pow((Math.Abs(p) - minP) / (maxP - minP), 1.0 / v);
            }


            SearchIO.output("", "", "", "p=" + p + ",q=" + q,
                            "p = " + p + " changed to q = " + q);
        }
コード例 #18
0
        /// <summary>
        /// Calculates the specified function.
        /// </summary>
        /// <param name="function">The function.</param>
        /// <param name="point">The point.</param>
        /// <returns>System.Double.</returns>
        internal double calculate(IOptFunction function, double[] point)
        {
            double fValue;
            var    pointClone = (double[])point.Clone();

            SearchIO.output("evaluating x =" + point.MakePrintString(), 4);
            if (functionData[function].TryGetValue(pointClone, out fValue))
            {
                SearchIO.output("f =" + fValue + " (from store).", 4);
                return(fValue);
            }
            calc_dependent_Analysis(point);
            /**************************************************/
            /*** This is the only function that should call ***/
            /**********IOptFunction.calculate(x)***************/
            fValue = function.calculate(point);
            /**************************************************/
            functionData[function].Add(pointClone, fValue);
            functionData[function].numEvals++;
            SearchIO.output("f =" + fValue + " (f'n eval #" + numEvals + ")", 4);
            return(fValue);
        }
コード例 #19
0
        private Boolean findFeasibleStartPoint()
        {
            var average = StarMath.norm1(x) / x.GetLength(0);
            var randNum = new Random();

            // n-m variables can be changed

            //double[,] gradH = calc_h_gradient(x);

            for (var outerK = 0; outerK < feasibleOuterLoopMax; outerK++)
            {
                SearchIO.output("looking for feasible start point (attempt #" + outerK, 4);
                for (var innerK = 0; innerK < feasibleOuterLoopMax; innerK++)
                {
                    // gradA = calc_h_gradient(x, varsToChange);
                    // invGradH = StarMath.inverse(gradA);
                    //x = StarMath.subtract(x, StarMath.multiply(invGradH, calc_h_vector(x)));
                    if (feasible(x))
                    {
                        return(true);
                    }
                }
                for (var i = 0; i < n; i++)
                {
                    x[i] += 2 * average * (randNum.NextDouble() - 0.5);
                }

                //gradA = calc_h_gradient(x);
                //invGradH = StarMath.inverse(gradA);
                if (feasible(x))
                {
                    return(true);
                }
            }
            return(false);
        }
コード例 #20
0
        protected override double run(out double[] xStar)
        {
            //evaluate f(x0)
            fStar = fk = calc_f(x);

            // the search direction is initialized.
            dk = new double[n];

            active.AddRange(h.Cast <IConstraint>());

            do
            {
                gradF = calc_f_gradient(x);
                A     = formulateActiveSetAndGradients(x);
                double initAlpha;
                dk = calculateSQPSearchDirection(x, out initAlpha);
                meritFunction.penaltyWeight = adjustMeritPenalty();
                // this next function is not part of the regular SQP algorithm
                // it's only intended to keep all the points in the positive space.
                initAlpha = preventNegatives(x, dk, initAlpha);
                //

                alphaStar = lineSearchMethod.findAlphaStar(x, dk, initAlpha);
                x         = x.add(StarMath.multiply(alphaStar, dk));
                SearchIO.output("iteration=" + k, 3);
                SearchIO.output("--alpha=" + alphaStar, 3);
                k++;
                fk = calc_f(x);

                SearchIO.output("----f = " + fk, 3);
                SearchIO.output("---#active =" + active.Count, 3);
            } while (notConverged(k, numEvals, fk, x, null, gradF));
            fStar = fk;
            xStar = (double[])x.Clone();
            return(fStar);
        }
コード例 #21
0
        private double run(out double[] xStar, double[] xInit)
        {
            xStar = null;
            fStar = double.PositiveInfinity;
            // k = 0 --> iteration counter
            k = 0;

            if (RequiresObjectiveFunction && (f.Count == 0))
            {
                SearchIO.output("No objective function specified.", 0);
                return(fStar);
            }
            if (RequiresSearchDirectionMethod && (searchDirMethod == null))
            {
                SearchIO.output("No search direction specified.", 0);
                return(fStar);
            }
            if (RequiresLineSearchMethod && (lineSearchMethod == null))
            {
                SearchIO.output("No line search method specified.", 0);
                return(fStar);
            }
            if (RequiresConvergenceCriteria && ConvergenceMethods.Count == 0)
            {
                SearchIO.output("No convergence method specified.", 0);
                return(fStar);
            }
            if (RequiresMeritFunction && (g.Count + h.Count > 0))
            {
                if (meritFunction == null)
                {
                    SearchIO.output("No merit function specified.", 0);
                    return(fStar);
                }
                else
                {
                    SearchIO.output("Constraints will be solved with penalty function.", 4);
                }
            }
            if (g.Count == 0)
            {
                SearchIO.output("No inequalities specified.", 4);
            }
            if (h.Count == 0)
            {
                SearchIO.output("No equalities specified.", 4);
            }
            if (InequalitiesConvertedToEqualities && (g.Count > 0))
            {
                SearchIO.output(g.Count + " inequality constsraints will be converted to equality" +
                                " constraints with the addition of " + g.Count + " slack variables.", 4);
            }

            if (RequiresAnInitialPoint)
            {
                if (xInit != null)
                {
                    xStart = (double[])xInit.Clone();
                    x      = (double[])xInit.Clone();
                }
                else if (xStart != null)
                {
                    x = (double[])xStart.Clone();
                }
                else
                {
                    // no? need a random start
                    x = new double[n];
                    var randy = new Random();
                    for (var i = 0; i < n; i++)
                    {
                        x[i] = 100.0 * randy.NextDouble();
                    }
                }
                if (RequiresFeasibleStartPoint && !feasible(x))
                {
                    if (!findFeasibleStartPoint())
                    {
                        return(fStar);
                    }
                }
            }
            p = h.Count;
            q = g.Count;
            m = p;

            if (n <= m)
            {
                if (n == m)
                {
                    SearchIO.output("There are as many equality constraints as design variables " +
                                    "(m = size). Consider another approach. Optimization is not needed.");
                }
                else
                {
                    SearchIO.output("There are more equality constraints than design variables " +
                                    "(m > size). Therefore the problem is overconstrained.");
                }
                return(fStar);
            }

            return(run(out xStar));
        }
コード例 #22
0
        /// <summary>
        /// Runs the specified x star.
        /// </summary>
        /// <param name="xStar">The x star.</param>
        /// <param name="xInit">The x initialize.</param>
        /// <returns>System.Double.</returns>
        private double run(out double[] xStar, double[] xInit)
        {
            xStar = null;
            fStar = double.PositiveInfinity;
            // k = 0 --> iteration counter
            k = 0;

            if ((spaceDescriptor != null) && (n != spaceDescriptor.n))
            {
                SearchIO.output("Differing number of variables specified. From space description = " + spaceDescriptor.n
                                + ", from x initial = " + n, 0);
                return(fStar);
            }
            if (RequiresObjectiveFunction && (f.Count == 0))
            {
                SearchIO.output("No objective function specified.", 0);
                return(fStar);
            }
            if (RequiresSearchDirectionMethod && (searchDirMethod == null))
            {
                SearchIO.output("No search direction specified.", 0);
                return(fStar);
            }
            if (RequiresLineSearchMethod && (lineSearchMethod == null))
            {
                SearchIO.output("No line search method specified.", 0);
                return(fStar);
            }
            if (RequiresConvergenceCriteria && ConvergenceMethods.Count == 0)
            {
                SearchIO.output("No convergence method specified.", 0);
                return(fStar);
            }
            if (RequiresMeritFunction && (g.Count + h.Count > 0))
            {
                if (meritFunction == null)
                {
                    SearchIO.output("No merit function specified.", 0);
                    return(fStar);
                }
                else
                {
                    SearchIO.output("Constraints will be solved with penalty function.", 4);
                }
            }
            if (RequiresDiscreteSpaceDescriptor && (spaceDescriptor == null))
            {
                SearchIO.output("No description of the discrete space is specified.");
                return(fStar);
            }
            if (g.Count == 0)
            {
                SearchIO.output("No inequalities specified.", 4);
            }
            if (h.Count == 0)
            {
                SearchIO.output("No equalities specified.", 4);
            }
            if (InequalitiesConvertedToEqualities && (g.Count > 0))
            {
                SearchIO.output(g.Count + " inequality constsraints will be converted to equality" +
                                " constraints with the addition of " + g.Count + " slack variables.", 4);
            }

            if (RequiresAnInitialPoint)
            {
                if (xInit != null)
                {
                    xStart = (double[])xInit.Clone();
                    x      = (double[])xInit.Clone();
                }
                else if (xStart != null)
                {
                    x = (double[])xStart.Clone();
                }
                else
                {
                    try
                    {
                        x = new RandomSampling(spaceDescriptor).GenerateCandidates(null, 1)[0];
                    }
                    catch
                    {
                        // no? need a random start
                        x = new double[n];
                        var randy = new Random();
                        for (var i = 0; i < n; i++)
                        {
                            x[i] = 100.0 * randy.NextDouble();
                        }
                    }
                }
                if (RequiresFeasibleStartPoint && !feasible(x))
                {
                    if (!findFeasibleStartPoint())
                    {
                        return(fStar);
                    }
                }
            }
            p = h.Count;
            q = g.Count;
            m = p;

            if (InequalitiesConvertedToEqualities && (q > 0))
            {
                var xnew = new double[n + q];
                for (var i = 0; i != n; i++)
                {
                    xnew[i] = x[i];
                }
                for (var i = n; i != n + q; i++)
                {
                    var sSquared = calculate(g[i - n], x);
                    if (sSquared < 0)
                    {
                        xnew[i] = Math.Sqrt(-sSquared);
                    }
                    else
                    {
                        xnew[i] = 0;
                    }
                    h.Add(new slackSquaredEqualityFromInequality(g[i - n], i, this));
                }
                x = xnew;
                n = x.GetLength(0);
                m = h.Count;
                p = h.Count;
            }
            if (n <= m)
            {
                if (n == m)
                {
                    SearchIO.output("There are as many equality constraints as design variables " +
                                    "(m = size). Consider another approach. Optimization is not needed.");
                }
                else
                {
                    SearchIO.output("There are more equality constraints than design variables " +
                                    "(m > size). Therefore the problem is overconstrained.");
                }
                return(fStar);
            }

            return(run(out xStar));
        }
コード例 #23
0
ファイル: NelderMead.cs プロジェクト: mdecourse/OOOT
        protected override double run(out double[] xStar)
        {
            vertices.Add(calc_f(x), x);
            // Creating neighbors in each direction and evaluating them
            for (var i = 0; i < n; i++)
            {
                var y = (double[])x.Clone();
                y[i] = (1 + initNewPointPercentage) * y[i] + initNewPointAddition;
                vertices.Add(calc_f(y), y);
            }

            while (notConverged(k, numEvals, vertices.Keys[0], vertices.Values[0], vertices.Values))
            {
                #region Compute the REFLECTION POINT

                // computing the average for each variable for n variables NOT n+1
                var Xm = new double[n];
                for (var dim = 0; dim < n; dim++)
                {
                    double sumX = 0;
                    for (var j = 0; j < n; j++)
                    {
                        sumX += vertices.Values[j][dim];
                    }
                    Xm[dim] = sumX / n;
                }

                var Xr = CloneVertex(vertices.Values[n]);
                for (var i = 0; i < n; i++)
                {
                    Xr[i] = (1 + rho) * Xm[i] - rho * Xr[i];
                }
                var fXr = calc_f(Xr);
                SearchIO.output("x_r = " + StarMathLib.StarMath.MakePrintString(Xr), 4);
                #endregion

                #region if reflection point is better than best

                if (fXr < vertices.Keys[0])
                {
                    #region Compute the Expansion Point
                    var Xe = CloneVertex(vertices.Values[n]);
                    for (var i = 0; i < n; i++)
                    {
                        Xe[i] = (1 + rho * chi) * Xm[i] - rho * chi * Xe[i];
                    }
                    var fXe = calc_f(Xe);
                    #endregion

                    vertices.RemoveAt(n);  // remove the worst
                    if (fXe < fXr)
                    {
                        vertices.Add(fXe, Xe);
                        SearchIO.output("expand", 4);
                    }
                    else
                    {
                        vertices.Add(fXr, Xr);
                        SearchIO.output("reflect", 4);
                    }
                }
                #endregion
                #region if reflection point is NOT better than best

                else
                {
                    #region but it's better than second worst, still do reflect

                    if (fXr < vertices.Keys[n - 1])
                    {
                        vertices.RemoveAt(n);  // remove the worst
                        vertices.Add(fXr, Xr);
                        SearchIO.output("reflect", 4);
                    }
                    #endregion

                    else
                    {
                        #region if better than worst, do Outside Contraction
                        if (fXr < vertices.Keys[n])
                        {
                            var Xc = CloneVertex(vertices.Values[n]);
                            for (var i = 0; i < n; i++)
                            {
                                Xc[i] = (1 + rho * psi) * Xm[i] - rho * psi * Xc[i];
                            }
                            var fXc = calc_f(Xc);

                            if (fXc <= fXr)
                            {
                                vertices.RemoveAt(n);  // remove the worst
                                vertices.Add(fXc, Xc);
                                SearchIO.output("outside constract", 4);
                            }
                            #endregion
                            #region Shrink all others towards best
                            else
                            {
                                var newXs = new List <double[]>();
                                for (var j = n; j >= 1; j--)
                                {
                                    var Xs = CloneVertex(vertices.Values[j]);
                                    for (var i = 0; i < n; i++)
                                    {
                                        Xs[i] = vertices.Values[0][i]
                                                + sigma * (Xs[i] - vertices.Values[0][i]);
                                    }
                                    newXs.Add(Xs);
                                    vertices.RemoveAt(j);
                                }
                                for (int j = 0; j < n; j++)
                                {
                                    vertices.Add(calc_f(newXs[j]), newXs[j]);
                                }
                                SearchIO.output("shrink towards best", 4);
                            }

                            #endregion
                        }
                        else
                        {
                            #region Compute Inside Contraction

                            var Xcc = CloneVertex(vertices.Values[n]);
                            for (var i = 0; i < n; i++)
                            {
                                Xcc[i] = (1 - psi) * Xm[i] + psi * Xcc[i];
                            }
                            var fXcc = calc_f(Xcc);

                            if (fXcc < vertices.Keys[n])
                            {
                                vertices.RemoveAt(n);  // remove the worst
                                vertices.Add(fXcc, Xcc);
                                SearchIO.output("inside contract", 4);
                            }
                            #endregion
                            #region Shrink all others towards best and flip over

                            else
                            {
                                var newXs = new List <double[]>();
                                for (var j = n; j >= 1; j--)
                                {
                                    var Xs = CloneVertex(vertices.Values[j]);
                                    for (var i = 0; i < n; i++)
                                    {
                                        Xs[i] = vertices.Values[0][i]
                                                - sigma * (Xs[i] - vertices.Values[0][i]);
                                    }
                                    newXs.Add(Xs);
                                    vertices.RemoveAt(j);
                                }
                                for (int j = 0; j < n; j++)
                                {
                                    vertices.Add(calc_f(newXs[j]), newXs[j]);
                                }
                                SearchIO.output("shrink towards best and flip", 4);
                            }

                            #endregion
                        }
                    }
                }

                #endregion

                k++;
                SearchIO.output("iter. = " + k, 2);
                SearchIO.output("Fitness = " + vertices.Keys[0], 2);
            } // END While Loop
            xStar = vertices.Values[0];
            fStar = vertices.Keys[0];
            vertices.Clear();
            return(fStar);
        }
コード例 #24
0
        protected override double run(out double[] xStar)
        {
            fStar = calc_f(x);
            // Set initial direction vectors to the basis vectors
            var directions       = new double[n][];
            var distanceTraveled = new double[n];
            var steps            = new double[n];

            for (int i = 0; i < n; i++)
            {
                var dir = new double[n];
                dir[i]        = 1.0;
                directions[i] = dir;
            }
            // Now, start the main loop
            while (notConverged(k++, numEvals, fStar, x))
            {
                SearchIO.output("iter=" + k, 2);
                // first, we move in each direction using simple line search
                for (var i = 0; i < n; i++)
                {
                    steps[i]            = initialStepSize;
                    distanceTraveled[i] = 0.0;
                    var oneSuccess = false;
                    var oneFailure = false;
                    while (!(oneFailure && oneSuccess) && Math.Abs(steps[i]) > minimumStepSize)
                    {
                        var xNew = x.add(directions[i].multiply(steps[i]));
                        var fNew = calc_f(xNew);
                        if (fNew < fStar)
                        {
                            oneSuccess           = true;
                            x                    = xNew;
                            fStar                = fNew;
                            distanceTraveled[i] += steps[i];
                            steps[i]            *= alpha;
                        }
                        else
                        {
                            oneFailure = true;
                            steps[i]  *= beta;
                        }
                    }
                }
                // finding new search directions
                var newDirs = new double[n][];
                for (int i = 0; i < n; i++)
                {
                    newDirs[i] = new double[n];
                    for (int j = i; j < n; j++)
                    {
                        newDirs[i] = newDirs[i].add(directions[j].multiply(distanceTraveled[j]));
                    }
                }
                initialStepSize = newDirs[0].norm2();
                if (initialStepSize < minimumStepSize)
                {
                    stepTooSmallConvergence.hasConverged = true;
                    continue;
                }
                directions[0] = newDirs[0].divide(initialStepSize);
                for (int i = 1; i < n; i++)
                {
                    var newDir = (double[])newDirs[i].Clone();
                    for (int j = 0; j < i; j++)
                    {
                        newDir = newDir.subtract(directions[j].multiply(newDirs[i].dotProduct(directions[j])));
                    }
                    var length = newDir.norm2();
                    directions[i] = (length == 0) ? new double[n] : newDir.divide(length);
                }
                // Next, we update the directions using the Gram-Schmidt Orthogonalization
            }
            xStar = x;
            return(fStar);
        }
コード例 #25
0
        /// <summary>
        /// Finds the alpha star.
        /// </summary>
        /// <param name="x">The x.</param>
        /// <param name="dir">The dir.</param>
        /// <returns>System.Double.</returns>
        public override double findAlphaStar(double[] x, double[] dir)
        {
            // include the first two points in this SortedList (essentially, the a, b and c).
            var alphaAndF = new SortedList <double, double>
            {
                { 0.0, calcF(x, 0.0, dir) },
                { stepSize, calcF(x, stepSize, dir) }
            };

            // third point is based on if second point is better or worse
            if (alphaAndF[stepSize] <= alphaAndF[0.0])
            {
                alphaAndF.Add(3 * stepSize, calcF(x, 3 * stepSize, dir));
            }
            else
            {
                alphaAndF.Add(stepSize / 2, calcF(x, stepSize / 2, dir));
            }

            var k        = 0;
            var fMin     = alphaAndF.Values.Min();
            var minIndex = alphaAndF.IndexOfValue(fMin);

            #region start main loop
            while (((Math.Abs(alphaAndF.Keys[2] - alphaAndF.Keys[0]) / 2) > epsilon) && (k++ < kMax))
            {
                k++;
                double alphaNew;
                DSCPowellLoopStatus loopStatus;
                #region find new alpha
                if (!quadraticApprox(out alphaNew, alphaAndF))
                {
                    /* if the quadratic approximatoin fails, we make note of it with this enumerator. */
                    loopStatus = DSCPowellLoopStatus.SecondDerivNegative;
                    SearchIO.output("<<< uh-oh! negative 2nd deriv @ k=" + k + "!>>>", 5);
                }
                else if (alphaAndF.Keys.Contains(alphaNew))
                {
                    /* if the alpha is already one of the three, then no point in keeping it. */
                    loopStatus = DSCPowellLoopStatus.NewPointAlreadyFound;
                    SearchIO.output("<<< uh-oh! new point is a repeat @ k=" + k + "!>>>", 5);
                }
                else
                {
                    var fNew = calcF(x, alphaNew, dir);
                    if (fNew > alphaAndF.Values.Min() && NewPointIsFarthest(alphaNew, alphaAndF.Keys, minIndex))
                    {
                        SearchIO.output("<<< uh-oh! new point is not best and too far away @ k=" + k + "!>>>", 5);

                        /* the new point is not the best and is farthest from the current best, so it will simply
                         * be deleted after it is added. That's not good. */
                        loopStatus = DSCPowellLoopStatus.NewPointIsFarthest;
                    }
                    else
                    {
                        /* whew! it looks like the new point (point d) is a keeper */
                        loopStatus = DSCPowellLoopStatus.Normal;
                        alphaAndF.Add(alphaNew, fNew);
                    }
                }
                #endregion
                #region if alpha via quadratic approximation failed, then set here.
                if (loopStatus != DSCPowellLoopStatus.Normal)
                {
                    switch (minIndex)
                    {
                    case 0:
                        alphaNew = alphaAndF.Keys[0] + (alphaAndF.Keys[0] - alphaAndF.Keys[2]);
                        break;

                    case 1:
                        alphaNew = (alphaAndF.Keys[0] + alphaAndF.Keys[1] + alphaAndF.Keys[2]) / 3;
                        break;

                    case 2:
                        alphaNew = alphaAndF.Keys[2] + (alphaAndF.Keys[2] - alphaAndF.Keys[0]);
                        break;
                    }
                    alphaAndF.Add(alphaNew, calcF(x, alphaNew, dir));
                }
                #endregion
                #region remove farthest value from min
                fMin     = alphaAndF.Values.Min();
                minIndex = alphaAndF.IndexOfValue(fMin);
                switch (minIndex)
                {
                case 0:
                    alphaAndF.RemoveAt(3); break;

                case 1:
                    if (alphaAndF.Keys[3] - alphaAndF.Keys[1] > alphaAndF.Keys[1] - alphaAndF.Keys[0])
                    {
                        alphaAndF.RemoveAt(3);
                    }
                    else
                    {
                        alphaAndF.RemoveAt(0);
                    }
                    break;

                case 2:
                    if (alphaAndF.Keys[3] - alphaAndF.Keys[2] > alphaAndF.Keys[2] - alphaAndF.Keys[0])
                    {
                        alphaAndF.RemoveAt(3);
                    }
                    else
                    {
                        alphaAndF.RemoveAt(0);
                    }
                    break;

                case 3:
                    alphaAndF.RemoveAt(0); break;
                }
                #endregion
                fMin     = alphaAndF.Values.Min();
                minIndex = alphaAndF.IndexOfValue(fMin);
            }
            #endregion

            return(alphaAndF.Keys[minIndex]);
        }
コード例 #26
0
        protected override double run(out double[] xStar)
        {
            xStar = null;
            var conjugateDirections = new List <double[]>();

            for (int i = 0; i < n; i++)
            {
                var direction = new double[n];
                direction[i] = 1;
                conjugateDirections.Add(direction);
            }
            fStar = fk = calc_f(x);
            do
            {
                var fBegin                = fk;
                var xinner                = (double[])x.Clone();
                var maxImprovement        = 0.0;
                var indexOfMaxImprovement = -1;
                var maxAlpha              = 0.0;
                var indexOfMaxAlpha       = -1;
                var minAlpha              = double.PositiveInfinity;
                var indexOfMinAlpha       = -1;
                for (int i = 0; i < n; i++)
                {
                    var dk = conjugateDirections[i];
                    alphaStar = lineSearchMethod.findAlphaStar(xinner, dk, true);
                    xinner    = xinner.add(StarMath.multiply(alphaStar, dk));
                    var fNew = calc_f(xinner);
                    if (Math.Abs(alphaStar) > Math.Abs(maxAlpha))
                    {
                        maxAlpha        = alphaStar;
                        indexOfMaxAlpha = i;
                    }
                    if (Math.Abs(alphaStar) < Math.Abs(minAlpha))
                    {
                        minAlpha        = alphaStar;
                        indexOfMinAlpha = i;
                    }
                    if (fk - fNew > maxImprovement)
                    {
                        maxImprovement        = fk - fNew;
                        indexOfMaxImprovement = i;
                    }
                    fk = fNew;
                    k++;
                }
                if (Math.Abs(maxAlpha) < minAlphaStepRatio || Math.Abs(minAlpha / maxAlpha) < minAlphaStepRatio)
                {
                    conjugateDirections.Clear();
                    for (int i = 0; i < n; i++)
                    {
                        var direction = new double[n];
                        direction[i] = 1;
                        conjugateDirections.Add(direction);
                    }
                }
                else
                {
                    /*combine direction search. */
                    var xJump = StarMath.multiply(2, xinner).subtract(x, n);
                    var fJump = calc_f(xJump);
                    if (fJump >= fBegin ||
                        (fBegin - 2 * fk + fJump) * (fBegin - fk - maxImprovement) * (fBegin - fk - maxImprovement)
                        >= (fBegin - fJump) * (fBegin - fJump) * maxImprovement / 2)
                    {
                        x = xinner;
                    }
                    else
                    {
                        var combinedDir = xinner.subtract(x, n).normalize();
                        alphaStar = lineSearchMethod.findAlphaStar(xinner, combinedDir, true);
                        x         = xinner.add(StarMath.multiply(alphaStar, combinedDir));
                        conjugateDirections.RemoveAt(indexOfMaxImprovement);
                        conjugateDirections.Add(combinedDir);
                        k++;
                        fk = calc_f(x);
                    }
                }
                if (fk < fStar)
                {
                    fStar = fk;
                    xStar = (double[])x.Clone();
                }
                SearchIO.output("iteration=" + k, 3);
                SearchIO.output("f = " + fk, 3);
            } while (notConverged(k, numEvals, fk, x, null, gradF));
            return(fStar);
        }