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.java
Data file(s): pfqcost.dat, pfubds.dat, pflcost.dat


xbportf.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbportf.java
  `````````````````
  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. */

import java.io.*;
import com.dashoptimization.*;

public class xbportf
{
 static final int NVal = 30;      /* Total number of values */
 static final int LIMIT = 20;     /* Maximum number to be chosen */

 static final String QFILE = System.getProperty("XPRBDATA") +
   "/portf/pfqcost.dat";          /* Quadratic cost coefficients */
 static final String BFILE = System.getProperty("XPRBDATA") +
   "/portf/pfubds.dat";           /* Upper bounds on percentages */
 static final String CFILE = System.getProperty("XPRBDATA") +
   "/portf/pflcost.dat";          /* Linear cost coefficients */

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

 static XPRB bcl;
 static XPRBprob p;

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

 static void modFolio() throws IOException
 {
  XPRBctr c;
  XPRBexpr le, qobj;
  XPRBvar[] x;                    /* Amount of a value taken into
                                     the portfolio */
  XPRBvar[] y;                    /* 1 if value i is chosen, else 0 */
  int i,j;
  
/**** VARIABLES ****/
  x = new XPRBvar[NVal];
  y = new XPRBvar[NVal];
  for(i=0;i<NVal;i++)
  {
   x[i] = p.newVar("x_"+(i+1), XPRB.PL, 0, UBnd[i]);
   y[i] = p.newVar("y_"+(i+1), XPRB.BV);
  }

/****OBJECTIVE****/
  qobj = new XPRBexpr();          /* Define the objective: total cost */
  for(i=0;i<NVal;i++)
  {
   qobj.add(x[i].mul(Cost[i]));
   qobj.add(x[i].sqr().mul(QCost[i][i]));
   for(j=i+1;j<NVal;j++)
    qobj.add(x[i].mul(QCost[i][j]).mul(x[j]));
  }
  p.setObj(qobj);
 
/**** CONSTRAINTS ****/
                  /* Amounts of values chosen must add up to 100% */
  le = new XPRBexpr();
  for(i=0;i<NVal;i++) le.add(x[i]); 
  p.newCtr("C1", le .eql(100) );

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

  le = new XPRBexpr();          /* Limit on total number of values */
  for(i=0;i<NVal;i++) le.add(y[i]); 
  p.newCtr("Card", le .lEql(LIMIT) );
   
/****SOLVING + OUTPUT****/
/*  p.print(); */		  /* Print out the problem definition */
  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 */   
  p.mipOptimize("");              /* Solve the MIQP-problem, use 'lpOptimize'
                                     to solve QP */

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


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

    /**** Initialize the stream tokenizer ****/
 static StreamTokenizer initST(FileReader file)
 {
  StreamTokenizer st=null;

  st= new StreamTokenizer(file);   /* Initialize the stream tokenizer */
  st.commentChar('!');             /* Use the character '!' for comments */
  st.eolIsSignificant(true);       /* Return end-of-line character */
  st.ordinaryChar(',');            /* Use ',' as separator */
  st.parseNumbers();               /* Read numbers as numbers (not strings)*/ 
  return st;
 }

    /**** Read data from files ****/
 static void readData() throws IOException
 {
  int i,j;
  double value;
  FileReader datafile=null;
  StreamTokenizer st;
 
  QCost = new double[NVal][NVal];
  Cost = new double[NVal];
  UBnd = new double[NVal];

        /* Read the quadratic cost data file */
  for(i=0;i<NVal;i++)
   for(j=0;j<NVal;j++)
    QCost[i][j]=0;                 /* Initialize Q to 0 */
  datafile = new FileReader(QFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_NUMBER) break; 
   i=(int)st.nval;
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   j = (int)st.nval;
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   QCost[i-1][j-1] = st.nval;
  } while( st.nextToken() == st.TT_EOL );
  datafile.close();

        /* Read the linear cost data file */
  datafile = new FileReader(CFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_NUMBER) break; 
   i=(int)st.nval;
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   Cost[i-1] = st.nval;
  } while( st.nextToken() == st.TT_EOL );
  datafile.close();

        /* Read the bounds data file */
  datafile = new FileReader(BFILE);
  st = initST(datafile);
  do
  {
   do
   { 
    st.nextToken();
   } while(st.ttype==st.TT_EOL);    /* Skip empty lines */
   if(st.ttype != st.TT_NUMBER) break; 
   i=(int)st.nval;
   if(st.nextToken() != ',') break;
   if(st.nextToken() != st.TT_NUMBER) break;
   UBnd[i-1] = st.nval; 
  } while( st.nextToken() == st.TT_EOL );
  datafile.close();
}

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

 public static void main(String[] args)
 {
  bcl = new XPRB();                /* Initialize BCL */
  p = bcl.newProb("Portfolio");    /* Create a new problem in BCL */ 
  try
  {
   readData();                     /* Data input from file */
   modFolio();                     /* Formulate and solve the problem */
  }
  catch(IOException e)
  {
   System.err.println(e.getMessage());
   System.exit(1);
  }
 }
}

© 2001-2020 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.