# C# Binary Nonlinear Programming Example

← All NMath Code Examples

```using System;

using CenterSpace.NMath.Core;

namespace CenterSpace.NMath.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 );

// 0 <= x3 <= 4

// 0 <= x4 <= 4

// Add binary constraints for x0 and x1 (variable indices
// 0 and 1).

// And the integer constraint for x2 (variable index 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" );