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 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 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 */
            readData();                     /* Data input from file */
            modFolio(p);                     /* Formulate and solve the problem */
        }
    }
}

Back to examples browserPrevious exampleNext example