« Previous « Start » Next »
5 LPCON Problem
When solving a problem with a linear objective and nonlinear
constraints there is no need to explicitly code the gradient or
Hessian since these are implicitly given (the gradient is a constant
array and the Hessian is all zeros). TOMNET automatically supplies
these when inheriting from the linear problem class.
The linear constrained nonlinear programming problem is defined as:
|
|
f(x) = dT x |
|
|
s/t |
xL |
≤ |
x |
≤ |
xU |
bL |
≤ |
A x |
≤ |
bU |
cL |
≤ |
c(x) |
≤ |
cU |
|
|
(7) |
where
x,
xL,
xU,
d Rn,
f(
x)
R,
A
Rm1 × n,
bL,
bU Rm1 and
cL,
c(
x),
cU Rm2.
The solution
quickguide/lpconQG/lpconQG.sln defines an
example problem in TOMNET.
using System;
using TOMNET;
namespace TOMNET
{
/// <summary>
/// Quick guide class for linear problem
/// with both linear and nonlinear constraints.
/// </summary>
public class lpconQG : LinearProblem
{
/// <summary>
/// Constructor for Quick Guide Example for a linear
/// problem with both linear and nonlinear constraints.
/// </summary>
/// <param name="n">Number of variables.</param>
/// <param name="mLin">Number of linear constraints.</param>
/// <param name="mNonLin">Number of nonlinear constraints.</param>
/// <param name="c">Linear goal function.</param>
/// <param name="A">Linear constraints (row-based).</param>
/// <param name="b_L">Lower limits of linear constraints.</param>
/// <param name="b_U">Upper limits of linear constraints.</param>
/// <param name="x_0">Initial point.</param>
/// <param name="x_L">Lower limits of variables.</param>
/// <param name="x_U">Upper limits of variables.</param>
/// <param name="c_L">Lower limits of nonlinear constraints.</param>
/// <param name="c_U">Upper limits of nonlinear constraints.</param>
/// <param name="Name">Name of problem</param>
public lpconQG(int n, int mLin, int mNonLin, double[] c,
double[] A, double[] b_L, double[] b_U, double[] x_0,
double[] x_L, double[] x_U, double[] c_L, double[] c_U,
String Name) : base(c, A, b_L, b_U, x_L, x_U, x_0, Name,
double.NegativeInfinity, null, null)
{
//
// Nonlinear constraints.
//
this.mNonLin = mNonLin;
this.c_L = new double[mNonLin];
this.c_U = new double[mNonLin];
//
// Setting the nonlinear constraint bounds.
//
c_L.CopyTo(this.c_L, 0);
c_U.CopyTo(this.c_U, 0);
//
// Other parameters.
//
this.Name = Name;
}
/// <summary>
/// Nonlinear constraints.
/// </summary>
/// <param name="c">Nonlinear constraints in x.</param>
/// <param name="x">The decision variables.</param>
public override void c(double[] c, double[] x)
{
if (x[0] == 0 && x[1] == 0)
{
c[0] = 1.0;
}
else
{
c[0] = Math.Pow(x[0] * x[2] + x[1] * x[3], 2) /
(Math.Pow(x[0], 2) + Math.Pow(x[1], 2)) -
Math.Pow(x[2], 2) - Math.Pow(x[3], 2);
}
}
/// <summary>
/// Jacobian of nonlinear constraints.
/// </summary>
/// <param name="Jac">Jacobian of nonlinear constraints.</param>
/// <param name="x">The decision variables.</param>
public override void dc(Jacobian Jac, double[] x)
{
double h1 = Math.Pow(x[0], 2) + Math.Pow(x[1], 2);
double h2 = x[0] * x[2] + x[1] * x[3];
if (h1 == 0)
{
Jac[0, 0] = double.PositiveInfinity;
Jac[0, 1] = double.PositiveInfinity;
Jac[0, 2] = double.PositiveInfinity;
Jac[0, 3] = double.PositiveInfinity;
}
else
{
Jac[0,0] = 2* h2 * x[2]/h1 - 2 * x[0] * Math.Pow(h2/h1, 2);
Jac[0,1] = 2* h2 * x[3]/h1 - 2 * x[1] * Math.Pow(h2/h1, 2);
Jac[0,2] = 2* h2 * x[0]/h1 - 2 * x[2];
Jac[0,3] = 2* h2 * x[1]/h1 - 2 * x[3];
}
}
/// <summary>
/// Testprogram for lpconQG.
/// </summary>
static void Main()
{
//
// For use in bounds.
//
double Inf = double.PositiveInfinity;
//
// Number of decision variables, linear and nonlinear
// constraints, and name of the problem.
//
const int mLin = 3;
const int mNonLin = 1;
const int n = 4;
string Name = "lpconQG";
//
// Linear Constraints and the lower and upper bounds.
//
double[] A = new double[n * mLin] { 1, 0, -1, 0, 0, 1, 0, -1, 0,
0, 1, -1 };
double[] b_L = new double[mLin] { 1, 1, 0 };
double[] b_U = new double[mLin] { Inf, Inf, Inf };
//
// Lower and upper nonlinear constraint bounds.
//
double[] c_L = new double[mNonLin] { -1 };
double[] c_U = new double[mNonLin] { -1 };
//
// Lower and upper bounds for decision variables as well
// as the starting point for the solver.
//
double[] x_0 = new double[n] { 1, 0, 2, 0 };
double[] x_L = new double[n] { -Inf, -Inf, -Inf, 1 };
double[] x_U = new double[n] { 100, 100, 100, 100 };
//
// Entries for linear objective function.
//
double[] c = new double[n] { 3, 2, 0, 0 };
//
// Create a problem, solver and result instance.
//
lpconQG Prob = new lpconQG(n, mLin, mNonLin, c, A, b_L, b_U,
x_0, x_L, x_U, c_L, c_U, Name);
SNOPT solver = new SNOPT();
Result result;
//
// Define a print file for SNOPT.
//
string printfilename = "SnoptlpconQP.txt";
solver.Options.PrintFile = printfilename;
//
// Solve the problem.
//
solver.Solve(Prob, out result);
//
// Get the solution results.
//
double[] solution = result.x_k;
double objective = result.f_k;
//
// Display the solution on the console.
//
Console.WriteLine(" * * * * * * * *");
Console.WriteLine(" * Solved " + Prob.Name);
Console.WriteLine(" * Printfile: " + printfilename);
Console.WriteLine(" * Objective: {0}", objective);
Console.WriteLine(" * Solution");
Console.WriteLine(" x_L[i] <= x_k[i] <= x_U[i]");
for (int i = 0; i < Prob.N; i++)
{
Console.WriteLine(" {0,10:g3} <= {1,10:g3} <= {2,10:g3} ",
Prob.x_L[i], result.x_k[i], Prob.x_U[i]);
}
Console.WriteLine(" * Linear constraints");
double[] Ax = Prob.A.Evaluate(result.x_k);
Console.WriteLine(" b_L[i] <= (A*x)[i] <= b_U[i]");
for (int i = 0; i < Prob.mLin; i++)
{
Console.WriteLine(" {0,10:g3} <= {1,10:g3} <= {2,10:g3}",
Prob.A.GetLowerBound(i), Ax[i], Prob.A.GetUpperBound(i));
}
Console.WriteLine(" * Nonlinear constraint");
Console.WriteLine(" c_L[i] <= cx[i] <= b_U[i]");
double[] cx = new double[Prob.mNonLin];
Prob.c(cx, result.x_k);
for (int i = 0; i < Prob.mNonLin; i++)
{
Console.WriteLine(" {0,10:g3} <= {1,10:g3} <= {2,10:g3}",
Prob.c_L[i], cx[i], Prob.c_U[i]);
}
}
}
}
Observe that the code defines two functions that are used in the
callback from the solvers. The d2c function is currently not
implemented.
c: Nonlinear constraint vector
dc: Nonlinear constraint gradient matrix
d2c: The second part of the Hessian to the Lagrangian
function for the nonlinear constraints.
The
lpconQG.sln may be opened by a suitable editor and
compiled to an exe file. When running the executable from a command
prompt the following output results are displayed:
« Previous « Start » Next »