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.

xbportfcpp.zip[download all files]

Source Files

Data Files





xbportf.cxx

/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

  file xbportf.cxx
  ````````````````
  Quadratic portfolio model.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Mar. 2011
********************************************************/

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

#include <iostream>
#include <cstring>
#include <cstdio>
#include "xprb_cpp.h"
#include "xprs.h"

using namespace std;
using namespace ::dashoptimization;

#define NVal 30                       /* Total number of values */
#define LIMIT 20                      /* Maximum number to be chosen */

#define QFILE XPRBDATAPATH "/portf/pfqcost.dat" /* Quadratic cost coeff.s */
#define BFILE XPRBDATAPATH "/portf/pfubds.dat"  /* Upper bds. on percentages */
#define CFILE XPRBDATAPATH "/portf/pflcost.dat" /* Linear cost coefficients */

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

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

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

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

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

/****OBJECTIVE****/
 for(i=0;i<NVal;i++)              /* Define objective: total cost */
 {
  qobj += Cost[i]*x[i];
  qobj += QCost[i][i]*sqr(x[i]);
  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", x[i] <= UBnd[i]*y[i]);
 
 le = 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();			  ~~COMMENT25~~
 p.exportProb(XPRB_MPS,"Portf");  /* Output the matrix in MPS format */
 p.exportProb(XPRB_LP,"Portf");   /* Output the matrix in LP format */
  
 p.setSense(XPRB_MINIM);      	  /* Choose the sense of the optimization */   
 XPRSsetintcontrol(p.getXPRSprob(),XPRS_CUTSTRATEGY,0);
 p.lpOptimize("");                /* Solve the QP-problem, use 'mipOptimize' to
                                     solve MIQP */

 cout << "Objective function value: " << p.getObjVal() << endl;
 for(i=0;i<NVal;i++)
  cout << x[i].getName() << ": " << x[i].getSol() << ", ";
 cout << endl;
}

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

    /**** Read data from files ****/
void readData()
{
 int i,j;
 double value;
 FILE *datafile;
 
        /* Read the quadratic cost data file */
 memset(QCost,0,NVal*NVal*sizeof(double));      /* Initialize Q to 0 */
 datafile=fopen(QFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,i,g", &i, &j, 
        &value) == 3)
  QCost[i-1][j-1]=value; 
 fclose(datafile);

        /* Read the linear cost data file */
 datafile=fopen(CFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,g", &i, &value) == 2)
  Cost[i-1]=value; 
 fclose(datafile);

        /* Read the bounds data file */
 datafile=fopen(BFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "i,g", &i, &value) == 2)
  UBnd[i-1]=value;  
 fclose(datafile);
}

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

int main(int argc, char **argv)
{
 readData();                          /* Data input from file */
 modFolio();                          /* Formulate and solve the problem */
 
 return 0;
} 

Back to examples browserPrevious exampleNext example