using System; using CenterSpace.NMath.Core; namespace CenterSpace.NMath.Examples.CSharp { class SimpleNonlinearProgrammingExample { /// Example illustrating using the class ActiveSetLineSearchSQP to solve a /// NonLinear Programming (NLP) problem with linear constraints and variable /// bounds. static void Main( string[] args ) { // min -x0*x1*x2 // 0 <= x0 + 2*x1 + 2*x2 <= 72, // 0 <= x0, x1, x2 <= 42 // Dimensionality of the domain of the objective function. int xDim = 3; var objective = new Func<DoubleVector, double>( ( DoubleVector x ) => -x[0] * x[1] * x[2] ); var problem = new NonlinearProgrammingProblem( xDim, objective ); // Add variable bounds. for ( int i = 0; i < xDim; i++ ) { // Add a lower bound of 0 and upper bound of 42 for the ith variable. problem.AddBounds( i, 0.0, 42.0 ); } // Add the constraint 0 <= x0 + 2*x1 + 2*x2 <= 72. Note that this // is a linear constraint. problem.AddLinearConstraint( new DoubleVector( 1.0, 2.0, 2.0 ), 0.0, 72 ); // Pick the point (1, 1, 1) as initial solution guess. var x0 = new DoubleVector( 3, 1.0 ); // Pick a tolerance for convergence. The iteration will stop when // either the magnitude of the predicted function value change or the // magnitude of the step direction is less than the specified tolerance. double tolerance = 1e-4; var solver = new ActiveSetLineSearchSQP( tolerance ); bool success = solver.Solve( problem, x0 ); Console.WriteLine(); Console.WriteLine( "Termination status = " + solver.SolverTerminationStatus ); Console.WriteLine( "X = " + solver.OptimalX ); Console.WriteLine( "f(x) = " + solver.OptimalObjectiveFunctionValue ); Console.WriteLine( "Iterations = " + solver.Iterations ); // Seems like it took quite a few iterations to converge. Note that the // solver computes a step direction and a step size at each iteration. // The step direction is computed by forming a quadratic programming // problem with linear constraints at each iteration whose solution // yields the step direction. The size of the step taken in this // direction is then chosen to decrease the function value and not // violate constraints. Since our constraints for this problem are linear // to begin with, we may try taking a larger step in order to converge // faster. Well use the ConstantSQPstepSize class with a constant step // size of one and see what happens. solver.SolverOptions.StepSizeCalculator = new ConstantSQPStepSize( 1 ); success = solver.Solve( problem, x0 ); Console.WriteLine( "\nUsing a constant step size of 1:" ); Console.WriteLine( "Termination status = " + solver.SolverTerminationStatus ); Console.WriteLine( "X = " + solver.OptimalX ); Console.WriteLine( "f(x) = " + solver.OptimalObjectiveFunctionValue ); Console.WriteLine( "Iterations = " + solver.Iterations ); // As you can see the algorithm converges must faster with the constant // step size of one. In general if your constraints are all linear, or // very nearly linear, the constant step size calculator may yield // faster convergence. Console.WriteLine(); Console.WriteLine( "Press Enter Key" ); Console.Read(); } } }← All NMath Code Examples