/********************************************************
Xpress-BCL Java Example Problems
================================
file xbportf.java
`````````````````
Quadratic portfolio model.
(c) 2008-2023 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 */
}
}
}
|