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); }
/// <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); }
/// <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]); }
/// <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); }
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); } } }
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)); }
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); }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }
/// <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); }
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); }
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); }
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)); }
/// <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)); }
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); }
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); }
/// <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]); }
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); }