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.

xbrecurscs.zip[download all files]

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





xbrecurs.cs

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

    }

}
Back to examples browserPrevious exampleNext example