/*************************************************************/
/* Xpress-BCL C# Example Problems */
/* ============================== */
/* */
/* file xbrecurs.cs */
/* ```````````````` */
/* Example for the use of Xpress-BCL */
/* (Recursion solving a non-linear financial planning */
/* problem) */
/* The problem is to solve */
/* net(t) = Payments(t) - interest(t) */
/* balance(t) = balance(t-1) - net(t) */
/* interest(t) = (92/365) * balance(t) * interest_rate */
/* where */
/* balance(0) = 0 */
/* balance[T] = 0 */
/* for interest_rate */
/* */
/* (c) 2008 Fair Isaac Corporation */
/* authors: S.Heipcke, D.Brett. */
/*************************************************************/
using System;
using System.Text;
using System.IO;
using Optimizer;
using BCL;
namespace Examples
{
public class TestAdvRecurse
{
int T = 6;
/****DATA****/
double X = 0.00; /* An INITIAL GUESS as to interest rate x */
double[] B = /* {796.35, 589.8918, 398.1351, 201.5451, 0.0, 0.0}; */
{1,1,1,1,1,1};
/* An INITIAL GUESS as to balances b(t) */
double[] P = {-1000, 0, 0, 0, 0, 0}; /* Payments */
double[] R = {206.6, 206.6, 206.6, 206.6, 206.6, 0}; /* " */
double[] V = {-2.95, 0, 0, 0, 0, 0}; /* " */
XPRBvar[] b; /* Balance */
XPRBvar x; /* Interest rate */
XPRBvar dx; /* Change to x */
XPRBctr[] interest;
XPRBctr ctrd;
XPRBprob p = new XPRBprob("Fin_nlp"); /* Initialize new BCL problem */
/*********************************************************************/
void modFinNLP()
{
XPRBvar[] i = new XPRBvar[T]; /* Interest */
XPRBvar[] n = new XPRBvar[T]; /* Net */
XPRBvar[] epl = new XPRBvar[T];
XPRBvar[] emn = new XPRBvar[T]; /* + and - deviations */
XPRBexpr cobj;
int t;
/****VARIABLES****/
b = new XPRBvar[T];
for(t=0;t<T;t++)
{
i[t]=p.newVar("i");
n[t] = p.newVar("n", BCLconstant.XPRB_PL,
-BCLconstant.XPRB_INFINITY, BCLconstant.XPRB_INFINITY);
b[t] = p.newVar("b", BCLconstant.XPRB_PL,
-BCLconstant.XPRB_INFINITY, BCLconstant.XPRB_INFINITY);
epl[t]=p.newVar("epl");
emn[t]=p.newVar("emn");
}
x=p.newVar("x");
dx = p.newVar("dx", BCLconstant.XPRB_PL,
-BCLconstant.XPRB_INFINITY, BCLconstant.XPRB_INFINITY);
i[0].fix(0);
b[T-1].fix(0);
/****OBJECTIVE****/
cobj = new XPRBexpr();
for (t = 0; t < T; t++)
{ /* Objective: get feasible */
cobj += epl[t];
cobj += emn[t];
}
p.setObj(p.newCtr("OBJ",cobj)); /* Select objective function */
p.setSense(BCLconstant.XPRB_MINIM);/* Set sense of optimization */
/****CONSTRAINTS****/
for(t=0;t<T;t++)
{ /* net = payments - interest */
p.newCtr("net", new XPRBexpr(n[t]) == new XPRBexpr(P[t] +
R[t] + V[t]) - new XPRBexpr(i[t]));
/* Money balance across periods */
if(t>0)
p.newCtr("bal", new XPRBexpr(b[t]) ==
new XPRBexpr(b[t-1]-n[t]));
else
p.newCtr("bal", new XPRBexpr(b[t]) ==
new XPRBexpr(-n[t]));
}
/* i(t) = (92/365)*( b(t-1)*X + B(t-1)*dx ) approx. */
interest = new XPRBctr[T];
for (t = 1; t < T; t++)
interest[t] = p.newCtr("int", X*b[t-1] + B[t-1]*dx + epl[t] -
emn[t] == new XPRBexpr(365/92.0 * i[t]));
ctrd = p.newCtr("def", new XPRBexpr(x) == new XPRBexpr(X) +
new XPRBexpr(dx));
}
/*********************************************************************/
/* Recursion loop (repeat until variation of x converges to 0): */
/* save current basis and the solutions for variables b[t] and x */
/* set the balance estimates B[t] to the value of b[t] */
/* set the interest rate estimate X to the value of x */
/* reload the problem and the saved basis */
/* solve the LP and calculate the variation of x */
/*********************************************************************/
void solveFinNLP()
{
XPRBbasis basis;
double variation=1.0, oldval, XC;
double[] BC = new double[T];
int t, ct=0;
XPRSprob xprsp = p.getXPRSprob();
xprsp.CutStrategy = 0;
/* Switch automatic cut generation off */
p.lpOptimize(); /* Solve the LP-problem */
while(variation>0.000001)
{
ct++;
basis=p.saveBasis(); /* Save the current basis */
/* Get the solution values for b and x */
for(t=1;t<T;t++) BC[t-1]=b[t-1].getSol();
XC=x.getSol();
System.Console.Write("Loop " + ct + ": " + x.getName() + ":" +
x.getSol() + " (variation:" + variation + ")\n");
for(t=1;t<T;t++) /* Change coefficients in interest[t] */
{
interest[t].setTerm(dx, BC[t-1]);
B[t-1]=BC[t-1];
interest[t].setTerm(b[t-1], XC);
}
ctrd.setTerm(XC); /* Change constant term of ctrd */
X=XC;
oldval=XC;
p.loadMat(); /* Reload the problem */
p.loadBasis(basis); /* Load the saved basis */
basis.reset(); /* No need to keep the basis any longer */
p.lpOptimize(); /* Solve the LP-problem */
variation=System.Math.Abs(x.getSol()-oldval);
}
/* Get objective value */
System.Console.Write("Objective: " + p.getObjVal() + "\n");
System.Console.Write("Interest rate: " + x.getSol() +
"\nBalances: ");
/* Print out the solution values */
for(t=0;t<T;t++)
System.Console.Write(b[t].getName() + ":" +
b[t].getSol() + " ");
System.Console.Write("\n");
}
/*********************************************************************/
public static void Main()
{
XPRB.init();
TestAdvRecurse InitClassInstance = new TestAdvRecurse();
InitClassInstance.b = new XPRBvar[InitClassInstance.T];
InitClassInstance.ctrd = new XPRBctr();
InitClassInstance.modFinNLP(); /* Model the problem */
InitClassInstance.solveFinNLP(); /* Solve the problem */
return;
}
}
} |