FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

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.

xbrecursjava.zip[download all files]

Source Files
By clicking on a file name, a preview is opened at the bottom of this page.
xbrecurs.java[download]





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 */
    }
  }
}

Back to examples browserPrevious exampleNext example