C# Simple Nonlinear Programming Example

← All NMath Code Examples

 

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
Top