/******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbcontr2s.java * ``````````````````` * Contract allocation example. * Combining BCL problem input with problem solving * and callbacks in Xpress-Optimizer. * -- Single MIP thread -- * * (c) 2008-2024 Fair Isaac Corporation * author: S.Heipcke, 2005, rev. Dec. 2011 ********************************************************/ import com.dashoptimization.*; import java.io.*; public class xbcontr2s { static final int District = 6; /* Number of districts */ static final int Contract = 10; /* Number of contracts */ /**** DATA ****/ static final int[] OUTPUT = {50, 40, 10, 20, 70, 50}; /* Max. output per district */ static final int[] COST = {50, 20, 25, 30, 45, 40}; /* Cost per district */ static final int[] VOLUME = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20}; /* Volume of contracts */ /***********************************************************************/ static class IntSolCallback implements XPRSintSolListener { public void XPRSintSolEvent(XPRSprob oprob, Object data) { int num, d, c; XPRBprob bprob; XPRBvar y; try { bprob = (XPRBprob) data; num = oprob.getIntAttrib(XPRS.MIPSOLS); /* Get number of the solution */ bprob.sync(XPRB.XPRS_SOL); /* Update BCL solution values */ System.out.println("Solution " + num + ": Objective value: " + bprob.getObjVal()); for (d = 0; d < District; d++) for (c = 0; c < Contract; c++) { y = bprob.getVarByName("q_d" + (d + 1) + "_c" + (c + 1)); if ((y.getColNum() > -1) && (y.getSol() != 0)) System.out.println(y.getName() + ": " + y.getSol()); } } catch (XPRSprobException e) { System.out.println("Error " + e.getCode() + ": " + e.getMessage()); } } } /***********************************************************************/ public static void main(String[] args) throws XPRSexception { try (XPRBprob p = new XPRBprob("Contract2"); /* Initialize BCL and create a new problem */ XPRBexprContext context = new XPRBexprContext(); /* Release XPRBexpr instances at end of block. */ XPRS xprs = new XPRS()) { /* Initialize Xpress-Optimizer */ int d, c, i, stat, ncol, len; double[] sol; double val; java.lang.String[] names; XPRSprob op; IntSolCallback cb; XPRBexpr l1, l2, lobj; XPRBvar[][] x; /* Variables indicating whether a project is chosen */ XPRBvar[][] y; /* Quantities allocated to contractors */ /**** VARIABLES ****/ x = new XPRBvar[District][Contract]; y = new XPRBvar[District][Contract]; for (d = 0; d < District; d++) for (c = 0; c < Contract; c++) { x[d][c] = p.newVar("x_d" + (d + 1) + "_c" + (c + 1), XPRB.BV); y[d][c] = p.newVar("q_d" + (d + 1) + "_c" + (c + 1), XPRB.SC, 0, OUTPUT[d]); y[d][c].setLim(5); } /****OBJECTIVE****/ lobj = new XPRBexpr(); for (d = 0; d < District; d++) for (c = 0; c < Contract; c++) lobj.add(y[d][c].mul(COST[d])); p.setObj(lobj); /* Set the objective function */ /**** CONSTRAINTS ****/ for (c = 0; c < Contract; c++) { l1 = new XPRBexpr(); l2 = new XPRBexpr(); for (d = 0; d < District; d++) { l1.add(y[d][c]); l2.add(x[d][c]); } p.newCtr("Size", l1.gEql(VOLUME[c])); /* "Size": cover the req. volume */ p.newCtr("Min", l2.gEql(2)); /* "Min": at least 2 districts / contract */ } for (d = 0; d < District; d++) { /* Do not exceed max. output */ l1 = new XPRBexpr(); for (c = 0; c < Contract; c++) l1.add(y[d][c]); p.newCtr("Output", l1.lEql(OUTPUT[d])); } for (d = 0; d < District; d++) /* If a contract is allocated to a district, then at least 1 unit is allocated to it */ for (c = 0; c < Contract; c++) p.newCtr("XY", x[d][c].lEql(y[d][c])); /****SOLVING + OUTPUT****/ /* Desactivate parallel MIP (for synchronization of BCL and Optimizer) */ p.getXPRSprob().setIntControl(XPRS.MIPTHREADS, 1); cb = new IntSolCallback(); p.getXPRSprob().addIntSolListener(cb, p); /* Define an integer solution callback */ p.mipOptimize(""); /* Solve the MIP problem */ } } }