| |||||||||||
Recurse - A successive linear programming model Description A non-linear problem (quadratic terms in the constraints) is
modeled as a successive linear
programming (SLP) model. (SLP is also known as 'recursion'.)
The constraint coefficients are changed iteratively. Shows
how to save and re-load an LP basis.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
xbrecurs.java /******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbrecurs.java * `````````````````` * 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-2024 Fair Isaac Corporation * author: S.Heipcke, 2001, rev. Mar. 2011 ********************************************************/ import com.dashoptimization.*; public class xbrecurs { static final int T = 6; /****DATA****/ static double X = 0.00; /* An INITIAL GUESS as to interest rate x */ static final 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) */ static final double[] P = {-1000, 0, 0, 0, 0, 0}; /* Payments */ static final double[] R = {206.6, 206.6, 206.6, 206.6, 206.6, 0}; /* " */ static final double[] V = {-2.95, 0, 0, 0, 0, 0}; /* " */ static XPRBvar[] b; /* Balance */ static XPRBvar x; /* Interest rate */ static XPRBvar dx; /* Change to x */ static XPRBctr[] interest; static XPRBctr ctrd; /***********************************************************************/ static void modFinNLP(XPRBprob p) throws XPRSexception { XPRBvar[] i; /* Interest */ XPRBvar[] n; /* Net */ XPRBvar[] epl, emn; /* + and - deviations */ XPRBexpr cobj, le; int t; /****VARIABLES****/ b = new XPRBvar[T]; i = new XPRBvar[T]; n = new XPRBvar[T]; epl = new XPRBvar[T]; emn = new XPRBvar[T]; for (t = 0; t < T; t++) { i[t] = p.newVar("i"); n[t] = p.newVar("n", XPRB.PL, -XPRB.INFINITY, XPRB.INFINITY); b[t] = p.newVar("b", XPRB.PL, -XPRB.INFINITY, XPRB.INFINITY); epl[t] = p.newVar("epl"); emn[t] = p.newVar("emn"); } x = p.newVar("x"); dx = p.newVar("dx", XPRB.PL, -XPRB.INFINITY, 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.add(epl[t]).add(emn[t]); p.setObj(cobj); /* Select objective function */ p.setSense(XPRB.MINIM); /* Choose the sense of the optimization */ /****CONSTRAINTS****/ for (t = 0; t < T; t++) { /* net = payments - interest */ p.newCtr("net", n[t].eql(i[t].mul(-1).add(P[t]).add(R[t]).add(V[t]))); /* Money balance across periods */ if (t > 0) p.newCtr("bal", b[t].eql(b[t - 1].add(n[t].mul(-1)))); else p.newCtr("bal", b[t].eql(n[t].mul(-1))); } interest = new XPRBctr[T]; for (t = 1; t < T; t++) /* i(t) = (92/365)*( b(t-1)*X + B(t-1)*dx ) approx. */ interest[t] = p.newCtr( "int", b[t - 1] .mul(X) .add(dx.mul(B[t - 1])) .add(epl[t]) .add(emn[t]) .eql(i[t].mul(365 / 92.0))); ctrd = p.newCtr("def", x.eql(dx.add(X))); /* x = dx + X */ } /**************************************************************************/ /* Recursion loop (repeat until variation of x converges to 0): */ /* save the 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 */ /**************************************************************************/ static void solveFinNLP(XPRBprob p) throws XPRSexception { XPRBbasis basis; double variation = 1.0, oldval, XC; double[] BC; int t, ct = 0; p.getXPRSprob().setIntControl(XPRS.CUTSTRATEGY, 0); /* Switch automatic cut generation off */ p.lpOptimize(""); /* Solve the LP-problem */ BC = new double[T]; 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.out.println( "Loop " + ct + ": " + x.getName() + ":" + x.getSol() + " (variation:" + variation + ")"); 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 = null; /* No need to keep the basis any longer */ p.lpOptimize(""); /* Solve the LP-problem */ variation = Math.abs(x.getSol() - oldval); } System.out.println("Objective: " + p.getObjVal()); /* Get objective value */ System.out.println("Interest rate: " + x.getSol() * 100 + "%"); System.out.print("Balances: "); for (t = 0; t < T; t++) /* Print out the solution values */ System.out.print(b[t].getName() + ":" + b[t].getSol() + " "); System.out.println(); } /***********************************************************************/ public static void main(String[] args) throws XPRSprobException, XPRSexception { try (XPRBprob p = new XPRBprob("Fin_nlp"); /* Initialize BCL and create a new problem*/ XPRBexprContext context = new XPRBexprContext(); /* Release XPRBexpr instances at end of block. */ XPRS xprs = new XPRS()) { /* Initialize Xpress-Optimizer */ modFinNLP(p); /* Model the problem */ solveFinNLP(p); /* Solve the problem */ } } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |