Initializing help system before first use

Portfolio - Quadratic Programming with discrete variables


Type: Portfolio optimization
Rating: 2 (easy-medium)
Description: Quadratic Mixed Integer Programming example demonstrating Quadratic Programming with discrete variables.
File(s): xbportf.cs
Data file(s): pfqcost.dat, pfubds.dat, pflcost.dat


xbportf.cs
/********************************************************/
/*  Xpress-BCL C# Example Problems                      */
/*  ==============================                      */
/*                                                      */
/*  file xbportf.cs                                     */
/*  ```````````````                                     */
/*  Example for the use of Xpress-BCL                   */
/*  (Quadratic portfolio model)                         */
/*                                                      */
/*  (c) 2008 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 your own XPRBDATAPATH
        const string XPRBDATAPATH = "../../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();			  /* Print out the problem definition */
            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;
        } 

    }

}

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.