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