C# Binary Nonlinear Programming Example

← All NMath Code Examples

 

using System;

using CenterSpace.NMath.Core;
using CenterSpace.NMath.Analysis;

namespace CenterSpace.NMath.Analysis.Examples.CSharp
{
  /// <summary>
  /// A .NET example in C# showing how to solve a nonlinear programming problem
  /// that has some binary and integral constraints on its solution variables.
  /// </summary>
  public class BinaryNonlinearProgrammingExample
  {
    // The problem is:
    // min Z = x0 + 1.5*x1 + 0.5*x2 + x3^2 + x4^2
    // Subject to:
    // (x3 - 2)^2 - x4 <= 0,
    // x3 - 2*x0 => 0,
    // x3 - x4 - 4*(1-x1) <= 0,
    // x3 - (1 - x0) >= 0,
    // x4 - x1 >= 0,
    // x3 + x4 >= 3*x2,
    // x0 + x1 + x2 >= 1,
    // 0 <= x3 <= 4, 
    // 0 <= x4 <= 4,
    // In addition, x0, and x1 have binary constraints, and x2
    // has an integral constraint:
    // x0, x1, = 0, 1
    // x2 must be an integer.
    static void Main( string[] args )
    {
      // We have 5 variables, so 5 is the x, or domain, dimension. We need this
      // number when creating delegate functions with lambda expressions.
      int xDim = 5;
      
      // Create our objective function from a delegate and use it in the mixed 
      // integer problem constructor.
      var Z = new DoubleFunctionalDelegate( xDim, x => x[0] + 1.5 * x[1] + 0.5 * x[2] + x[3] * x[3] + x[4] * x[4] );

      var problem = new MixedIntegerNonlinearProgrammingProblem( Z );

      // Add the constraints to our problem.
      // (x3 - 2)^2 - x4 <= 0
      problem.AddUpperBoundConstraint( xDim, x => Math.Pow( x[3] - 2.0, 2 ) - x[4], 0.0 );

      // x3 - 2*x0 => 0
      problem.AddLowerBoundConstraint( xDim, x => x[3] - 2.0 * x[0], 0.0 );
      
      // x3 - x4 - 4*(1-x1) <= 0
      // or
      // x3 - x4 + 4*x1 <= 4
      problem.AddUpperBoundConstraint( xDim, x => x[3] - x[4] - 4.0 * ( 1.0 - x[1] ), 0.0 );

      // x3 - (1 - x0) >= 0
      // or
      // x3 + x0 >= 1
      problem.AddLowerBoundConstraint( xDim, x => x[3] - ( 1.0 - x[0] ), 0.0 );

      // x4 - x1 >= 0
      problem.AddLowerBoundConstraint( xDim, x => x[4] - x[1], 0.0 );

      // x3 + x4 >= 3*x2
      // or
      // x3 + x4 - 3*x2 >= 0
      problem.AddLowerBoundConstraint( xDim, x => x[3] + x[4] - 3.0 * x[2], 0.0 );

      // x0 + x1 + x2 >= 1
      problem.AddLowerBoundConstraint( xDim, x => x[0] + x[1] + x[2], 1.0 );

      // Add the variable bounds.
      // 0 <= x3 <= 4
      problem.AddBounds( 3, 0.0, 4.0 );

      // 0 <= x4 <= 4
      problem.AddBounds( 4, 0.0, 4.0 );

      // Add binary constraints for x0 and x1 (variable indices
      // 0 and 1).
      problem.AddBinaryConstraint( 0, 1 );
    
      // And the integer constraint for x2 (variable index 2).
      problem.AddIntegralConstraint( 2 );

      // Construct the solver and solver parameter objects.
      var solver = new StochasticHillClimbingSolver();
	  
      // The solver parameters will be passed to the solver when
      // we solve. Here we specify:
      //
      // Minimize the objective function,
      // and
      // Attempt to solve for at most 10 seconds (10000 milliseconds).
      // If the solver fails to converge in 10 seconds, it will return
      // and the Result field of the solver will have the value
      // SolverInterrupted.
      var solverParameters = new StochasticHillClimbingParameters 
      { 
        Minimize = true,
        TimeLimitMilliSeconds = 10000
      };

      // Solve the problem with using the solver parameters and print
      // out the results.
      solver.Solve( problem, solverParameters );
      Console.WriteLine( "Result: " + solver.Result );
      Console.WriteLine( "Optimal Solution: " + solver.OptimalX );
      Console.WriteLine( "Optimal Function Value: " + solver.OptimalObjectiveFunctionValue );

      // Note that a variable with an integer constraint may not get
      // an exact integer value in the solution. In this case x2, which
      // has an integral constraint gets a value of about 6.48e-9
      // which is very, very close to 0. In general if the
      // solver finds an optimal solution to a problem with integral 
      // constraints, the integrally constrained components of the 
      // solution should be rounded to the closest integer - or
      // cast to ints.

	  Console.WriteLine();
      Console.WriteLine( "Press Enter Key" );
      Console.Read();
    }
  }
}

← All NMath Code Examples
Top