« Previous « Start » Next »
6 QPCON Problem
When solving a problem with a quadratic objective and nonlinear
constraints TOMNET automatically supplies objective derivatives
(gradient and Hessian) if inheriting from the quadratic problem
class, as shown for the LPCON
5 problem.
The quadratic constrained nonlinear programming problem is defined
as:
|
|
|
|
|
s/t |
xL |
≤ |
x |
≤ |
xU |
bL |
≤ |
A x |
≤ |
bU |
cL |
≤ |
c(x) |
≤ |
cU |
|
|
(8) |
where
x,
xL,
xU,
d Rn,
F Rn
× n,
f(
x)
R,
A Rm1 ×
n,
bL,
bU Rm1 and
cL,
c(
x),
cU
Rm2.
The following file (maintained from
quickguide/qpconQG/qpconQG.sln) defines and solves an
example problem in TOMNET:
using System;
using TOMNET;
namespace TOMNET
{
/// <summary>
/// Quick guide class for quadratic problem with both
/// linear and nonlinear constraints.
/// </summary>
public class qpconQG : QuadraticProblem
{
/// <summary>
/// Constructor for Quadratic 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 part of goal function</param>
/// <param name="F">Quadratic part of 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 qpconQG(int n, int mLin, int mNonLin, double[] c,
double[] F, 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(n, mLin, F, c, A, b_L, b_U,
x_0, x_L, x_U)
{
//
// 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">Values of nonlinear constraints in x.</param>
/// <param name="x">The decision variables.</param>
public override void c(double[] c, double[] x)
{
c[0] = 0.0;
for (int i = 0; i < this.N; i++)
{
c[0] += Math.Pow(x[i], 2.0) / (1.0 + ((double)i) / 3.0);
}
}
/// <summary>
/// Jacobian for the 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)
{
for (int i = 0; i < this.N; i++)
{
Jac[0, i] = 2.0 * x[i] / (1.0 + ((double)i) / 3.0);
}
}
/// <summary>
/// Testprogram for qpconQG.
/// </summary>
static void Main()
{
//
// For use in bounds.
//
double Inf = double.PositiveInfinity;
//
// Name of the problem
//
string Name = "qpconQG";
//
// Number of decision variables, linear constraints and
// nonlinear constraints.
//
const int n = 10;
const int mLin = 8;
const int mNonLin = 1;
//
// Lower and upper bounds for linear constraints.
//
double[] b_L = new double[mLin] { 1, 1, 1, 1, 1, 1, 1, 1 };
double[] b_U = new double[mLin] { 1, 1, 1, 1, 1, 1, 1, 1 };
//
// Lower and upper bounds for nonlinear constraints.
//
double[] c_L = new double[mNonLin] { 4 };
double[] c_U = new double[mNonLin] { 4 };
//
// Lower and upper bounds for decision variables as well
// as the starting point for the solver.
//
double[] x_0 = new double[n] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
double[] x_L = new double[n] { -Inf, -Inf, -Inf, -Inf, -Inf,
-Inf, -Inf, -Inf, -Inf, -Inf };
double[] x_U = new double[n] { Inf, Inf, Inf, Inf, Inf,
Inf, Inf, Inf, Inf, Inf };
//
// Linear constraints
//
double[] A = new double[n * mLin];
for (int i = 0; i < mLin; i++)
{
for (int j = 0; j < n; j++)
{
if (i == j)
{
A[i * n + j] = 0.5;
}
else
{
A[i * n + j] = 1;
}
}
}
//
// Entries for linear part of the objective function
//
double[] c = new double[n] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
//
// Quadratic part of the objective function
//
double[] F = new double[100];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == i)
{
F[i + 10 * j] = -2;
}
else
{
F[i + 10 * j] = 0.0;
}
}
}
//
// Create a problem, solver and result instance.
//
qpconQG Prob = new qpconQG(n, mLin, mNonLin, c, F, 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 = "SnoptqpconQP.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,10:g3}", objective);
Console.WriteLine(" * Solution");
Console.WriteLine(" x_L[i] <= x_k[i] <= x_U[i]");
for (int i = 0; i < solution.Length; i++)
{
Console.WriteLine(" {0,10:g3} <= {1,10:g3} <= {2,10:g3} ",
Prob.x_L[i], solution[i], Prob.x_U[i]);
}
double[] Ax = Prob.A.Evaluate(result.x_k);
Console.WriteLine(" * Linear constraints");
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 constraints ");
Console.WriteLine(" c_L[i] <= cx[i] <= c_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]);
}
}
}
}
The constraints and an analytical Jacobian are defined in the
example class.
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 executable is created by compiling
qpconQG.sln . When
running it from a command prompt the output results should be as in
the following picture:
« Previous « Start » Next »