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.

xbportfjava.zip[download all files]

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

Data Files





xbportf.java

/********************************************************
 * Xpress-BCL Java Example Problems
 * ================================
 *
 * file xbportf.java
 * `````````````````
 * Quadratic portfolio model.
 *
 * (c) 2008-2024 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 com.dashoptimization.*;
import java.io.*;

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 void modFolio(XPRBprob p) 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) throws Exception {
    try (XPRBprob p = new XPRBprob("Portfolio"); /* Initialize BCL and create a new problem */
        XPRBexprContext context =
            new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) {
      readData(); /* Data input from file */
      modFolio(p); /* Formulate and solve the problem */
    }
  }
}

Back to examples browserPrevious exampleNext example