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