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

Portfolio - Quadratic Programming with discrete variables

Description
Quadratic Mixed Integer Programming example demonstrating Quadratic Programming with discrete variables.


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

Data Files





xbportf.cs

/********************************************************/
/*  Xpress-BCL C# Example Problems                      */
/*  ==============================                      */
/*                                                      */
/*  file xbportf.cs                                     */
/*  ```````````````                                     */
/*  Example for the use of Xpress-BCL                   */
/*  (Quadratic portfolio model)                         */
/*                                                      */
/*  (c) 2008-2024 Fair Isaac Corporation                */
/*      authors: S.Heipcke, D.Brett.                    */
/********************************************************/

/* In this model, a choice has to be made which values are taken   *
 * into a portfolio in order to minimize the total cost. The costs *
 * for some values are interrelated, introducing a quadratic part  *
 * to the objective function. Upper bounds are given on the total  *
 * number of values and the share of each value that may be taken. */

using System;
using System.Text;
using System.IO;
using Optimizer;
using BCL;


namespace Examples
{
    public class TestPortfolio
    {
        int NVal = 30;                       /* Total number of values */
        int LIMIT = 20;                      /* Maximum number to be chosen */

        //Define XPRBDATAPATH to wherever you have placed the data folder; here we expect it to be same directory as compiled example.
        static string XPRBDATAPATH = Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).FullName + "/Data";
        string QFILE = XPRBDATAPATH + "/portf/pfqcost.dat"; /* Quadratic cost coeff.s */
        string BFILE = XPRBDATAPATH + "/portf/pfubds.dat";  /* Upper bds. on percentages */
        string CFILE = XPRBDATAPATH + "/portf/pflcost.dat"; /* Linear cost coefficients */

        /**** DATA ****/
        double[] Cost;                    /* Coeff. of lin. part of the obj. */
        double[,] QCost;             /* Coeff. of quad. part of the obj. */
        double[] UBnd;                    /* Upper bound values */

        XPRBprob p = new XPRBprob("Portfolio");              /* Initialize a new problem in BCL */

        /***********************************************************************/

        public void modFolio()
        {
            XPRBexpr le = new XPRBexpr();
            XPRBexpr qobj = new XPRBexpr();
            XPRBvar[] x = new XPRBvar[NVal];                 /* Amount of a value taken into
            the portfolio */
            XPRBvar[] y = new XPRBvar[NVal];                 /* 1 if value i is chosen, else 0 */
            int i,j;
            XPRSprob xprsp;

            /**** VARIABLES ****/
            for(i=0;i<NVal;i++)
            {
                string xname = "x_" + (i + 1);
                string yname = "y_" + (i + 1);
                x[i] = p.newVar(xname, BCLconstant.XPRB_PL, 0, UBnd[i]);
                y[i] = p.newVar(yname, BCLconstant.XPRB_BV);
            }

            /****OBJECTIVE****/
            for(i=0;i<NVal;i++)              /* Define objective: total cost */
            {
                qobj += new XPRBexpr(Cost[i] * x[i]);
                qobj += QCost[i,i] * x[i].sqr();
                for(j=i+1;j<NVal;j++)
                    qobj += QCost[i,j]*(x[i]*x[j]);
            }
            p.setObj(qobj);                  /* Set objective function */

            /**** CONSTRAINTS ****/
            /* Amounts of values chosen must add up to 100% */
            for(i=0;i<NVal;i++) le += x[i];
            p.newCtr("C1", le == 100);

            for(i=0;i<NVal;i++)              /* Upper limits */
                p.newCtr("UL", new XPRBexpr(x[i]) <= new XPRBexpr(UBnd[i]*y[i]));

            le = new XPRBexpr(0);                          /* Limit on total number of values */
            for(i=0;i<NVal;i++) le += y[i];
            p.newCtr("Card", le <= LIMIT);

            /****SOLVING + OUTPUT****/
            // p.print();			  ~~COMMENT36~~
            p.exportProb(BCLconstant.XPRB_MPS, "Portf");  /* Output the matrix in MPS format */
            p.exportProb(BCLconstant.XPRB_LP, "Portf");   /* Output the matrix in LP format */

            p.setSense(BCLconstant.XPRB_MINIM);      	  /* Choose the sense of the optimization */

            //Set the optimizer problem and cutstrategy:
            xprsp = p.getXPRSprob();
            xprsp.CutStrategy = 0;

            p.lpOptimize();                     /* Solve the QP-problem, add flag 'g' to
            solve MIQP */

            System.Console.Write("Objective function value: " + p.getObjVal() + "\n");
            for(i=0;i<NVal;i++)
                System.Console.Write(x[i].getName() + ": " + x[i].getSol() + ", ");
            System.Console.Write("\n");
        }

        /***********************************************************************/

        /**** Read data from files ****/
        public void readData()
        {
            int i,j;
            FileStream file = new FileStream(QFILE, FileMode.Open, FileAccess.Read);
            StreamReader fileStreamIn = new StreamReader(file);
            object[] objRead;

            while (p.XPRBreadline(fileStreamIn, 200, "{i},{i},{g}", out objRead) == 3)
            {
                i = (int)objRead[0];
                j = (int)objRead[1];
                QCost[i-1, j-1] = (double)objRead[2];
            }
            fileStreamIn.Close();
            file.Close();

            /* Read the linear cost data file */
            file = new FileStream(CFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);

            while (p.XPRBreadline(fileStreamIn, 200, "{i},{g}", out objRead) == 2)
            {
                i = (int)objRead[0];
                Cost[i - 1] = (double)objRead[1];
            }
            fileStreamIn.Close();
            file.Close();

            /* Read the bounds data file */
            file = new FileStream(BFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);

            while (p.XPRBreadline(fileStreamIn, 200, "{i},{g}", out objRead) == 2)
            {
                i = (int)objRead[0];
                UBnd[i - 1] = (double)objRead[1];
            }
            fileStreamIn.Close();
            file.Close();

        }

        /***********************************************************************/

        public static void Main()
        {
            XPRB.init();

            TestPortfolio InitClassInstance = new TestPortfolio();

            InitClassInstance.Cost = new double[InitClassInstance.NVal];
            InitClassInstance.QCost = new double[InitClassInstance.NVal, InitClassInstance.NVal];
            InitClassInstance.UBnd = new double[InitClassInstance.NVal];

            InitClassInstance.readData();                          /* Data input from file */
            InitClassInstance.modFolio();                          /* Formulate and solve the problem */

            return;
        }

    }

}
Back to examples browserPrevious exampleNext example