| |||||||||||||
Els - An economic lot-sizing problem solved by cut-and-branch and branch-and-cut heuristics Description The version 'xbels' of this example shows how to implement cut-and-branch (= cut
generation at the root node of the MIP search) and 'xbelsc' implements a
branch-and-cut (= cut generation at the MIP search tree nodes)
algorithm using the cut manager.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
xbelsc.java /******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbelsc.java * ```````````````` * Economic lot sizing, ELS, problem, solved by adding * (l,S)-inequalities) in a branch-and-cut heuristic * (using the cut manager). * * ELS considers production planning over a horizon * of T periods. In period t, t=1,...,T, there is a * given demand DEMAND[t] that must be satisfied by * production prod[t] in period t and by inventory * carried over from previous periods. There is a * set-up up cost SETUPCOST[t] associated with * production in period t. The unit production cost * in period t is PRODCOST[t]. There is no inventory * or stock-holding cost. * *** This model cannot be run with a Community Licence *** * * (c) 2008-2024 Fair Isaac Corporation * author: S.Heipcke, 2005, rev. Mar. 2011 ********************************************************/ import com.dashoptimization.*; import java.util.*; public class xbelsc { static final double EPS = 1e-6; static final int T = 6; /* Number of time periods */ /****DATA****/ static final int[] DEMAND = {1, 3, 5, 3, 4, 2}; /* Demand per period */ static final int[] SETUPCOST = {17, 16, 11, 6, 9, 6}; /* Setup cost / period */ static final int[] PRODCOST = {5, 3, 2, 1, 3, 1}; /* Prod. cost / period */ static int[][] D; /* Total demand in periods t1 - t2 */ static XPRBvar[] prod; /* Production in period t */ static XPRBvar[] setup; /* Setup in period t */ static class myobj { XPRBprob prob; double tol; } ; /**************************************************************************/ /* Cut generation algorithm: */ /* get the solution values */ /* identify and set up violated constraints */ /* add cuts to the problem */ /**************************************************************************/ static class CutMgrCallback implements XPRScutMgrListener { public int XPRScutMgrEvent(XPRSprob oprob, Object data) { int t, l; boolean res; int ncut; /* Counter for cuts */ double[] solprod, solsetup; /* Solution values for var.s prod & setup */ double ds; XPRBexpr le; ArrayList<XPRBcut> cutlist; XPRBcut[] cuts; myobj mo; mo = (myobj) data; ncut = 0; cutlist = new ArrayList<XPRBcut>(); try { /* Get the solution values */ mo.prob.beginCB(oprob); mo.prob.sync(XPRB.XPRS_SOL); solprod = new double[T]; solsetup = new double[T]; for (t = 0; t < T; t++) { solprod[t] = prod[t].getSol(); solsetup[t] = setup[t].getSol(); } /* Search for violated constraints: */ for (l = 0; l < T; l++) { for (ds = 0.0, t = 0; t <= l; t++) { if (solprod[t] < D[t][l] * solsetup[t] + mo.tol) ds += solprod[t]; else ds += D[t][l] * solsetup[t]; } /* Add the violated inequality: the minimum of the actual production prod[t] and the maximum potential production D[t][l]*setup[t] in periods 0 to l must at least equal the total demand in periods 0 to l. sum(t=1:l) min(prod[t], D[t][l]*setup[t]) >= D[0][l] */ if (ds < D[0][l] - mo.tol) { le = new XPRBexpr(); for (t = 0; t <= l; t++) { if (solprod[t] < D[t][l] * solsetup[t] + mo.tol) le.add(prod[t]); else le.add(setup[t].mul(D[t][l])); } cutlist.add(mo.prob.newCut(le.gEql(D[0][l]))); ncut++; } } /* Add cuts to the problem */ if (ncut > 0) { cuts = new XPRBcut[ncut]; for (t = 0; t < ncut; t++) cuts[t] = (XPRBcut) cutlist.get(t); mo.prob.addCuts(cuts); System.out.println( "Cuts added: " + ncut + " (depth " + oprob.getIntAttrib(XPRS.NODEDEPTH) + ", node " + oprob.getIntAttrib(XPRS.NODES) + "), obj. " + oprob.getDblAttrib(XPRS.LPOBJVAL)); } mo.prob.endCB(); } catch (XPRSprobException e) { System.out.println("Error " + e.getCode() + ": " + e.getMessage()); } return 0; } } /***********************************************************************/ static void modEls(XPRBprob p) throws XPRSexception { int s, t, k; XPRBexpr cobj, le; D = new int[T][T]; for (s = 0; s < T; s++) for (t = 0; t < T; t++) for (k = s; k <= t; k++) D[s][t] += DEMAND[k]; /****VARIABLES****/ prod = new XPRBvar[T]; setup = new XPRBvar[T]; for (t = 0; t < T; t++) { prod[t] = p.newVar("prod" + (t + 1)); setup[t] = p.newVar("setup" + (t + 1), XPRB.BV); } /****OBJECTIVE****/ cobj = new XPRBexpr(); for (t = 0; t < T; t++) /* Minimize total cost */ cobj.add(setup[t].mul(SETUPCOST[t]).add(prod[t].mul(PRODCOST[t]))); p.setObj(cobj); /****CONSTRAINTS****/ /* Production in period t must not exceed the total demand for the remaining periods; if there is production during t then there is a setup in t */ for (t = 0; t < T; t++) p.newCtr("Production", prod[t].lEql(setup[t].mul(D[t][T - 1]))); /* Production in periods 0 to t must satisfy the total demand during this period of time */ for (t = 0; t < T; t++) { le = new XPRBexpr(); for (s = 0; s <= t; s++) le.add(prod[s]); p.newCtr("Demand", le.gEql(D[0][t])); } } /***********************************************************************/ static void treeCutGen(XPRBprob p) throws XPRSexception { XPRSprob oprob; myobj mo; CutMgrCallback cb; double feastol; int starttime, t; starttime = XPRB.getTime(); oprob = p.getXPRSprob(); /* Get Optimizer problem */ oprob.setIntControl(XPRS.LPLOG, 0); oprob.setIntControl(XPRS.MIPLOG, 3); oprob.setIntControl(XPRS.CUTSTRATEGY, 0); /* Disable automatic cuts */ oprob.setIntControl(XPRS.PRESOLVE, 0); /* Switch presolve off */ oprob.setIntControl(XPRS.EXTRAROWS, 5000); /* Reserve extra rows */ feastol = oprob.getDblControl(XPRS.FEASTOL); /* Get zero tolerance */ feastol *= 10; mo = new myobj(); mo.prob = p; mo.tol = feastol; p.setCutMode(1); cb = new CutMgrCallback(); oprob.addCutMgrListener(cb, mo); p.mipOptimize(""); /* Solve the MIP */ System.out.println( "(" + (XPRB.getTime() - starttime) / 1000.0 + " sec) MIP status " + p.getMIPStat() + ", best solution: " + p.getObjVal()); /* Print out the solution: */ for (t = 0; t < T; t++) System.out.println( "Period " + (t + 1) + ": prod " + prod[t].getSol() + " (demand: " + DEMAND[t] + ", cost: " + PRODCOST[t] + "), setup " + setup[t].getSol() + " (cost: " + SETUPCOST[t] + ")"); } /***********************************************************************/ public static void main(String[] args) throws XPRSprobException, XPRSexception { try (XPRBprob p = new XPRBprob("Els"); /* 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 */ modEls(p); /* Model the problem */ treeCutGen(p); /* Solve the problem */ } } } | |||||||||||||
© Copyright 2024 Fair Isaac Corporation. |