| |||||||||||||||||
Coco - A full production planning example Description The Coco productional planning problem: multi-item,
multi-period, multi-site production planning. A sequence
of model versions show how the model
was developed, to (a) use more sophisticated modeling features
and (b) to extend the model, taking it from a simple linear model
to one with fixed prices and logical decisions.
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Data Files xbcoco.java /******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbcoco.java * ```````````````` * Complete Coco Problem. * Specify phase by PHASE parameter. * Data input in the model, not via data files. * * (c) 2008-2024 Fair Isaac Corporation * author: S.Heipcke, Jan. 2000, rev. Mar. 2011 ********************************************************/ import com.dashoptimization.*; public class xbcoco { static final int PHASE = 5; /* Phase = 3: Multi-period parameterised model; mines always open * Phase = 4: Mines may open/closed freely; when closed save 20000 per month * Phase = 5: Once closed always closed; larger saving */ static final int NP = 2; /* Number of products (p) */ static final int NF = 2; /* factories (f) */ static final int NR = 2; /* raw materials (r) */ static final int NT = 4; /* time periods (t) */ /****DATA****/ static final double[][] REV = { {400, 380, 405, 350}, {410, 397, 412, 397} }; /* Unit selling price of prod. p in period t */ static final double[][] CMAK = { {150, 153}, {75, 68} }; /* Unit cost to make product p at factory f */ static final double[][] CBUY = { {100, 98, 97, 100}, {200, 195, 198, 200} }; /* Unit cost to buy raw material r in period t */ static final double[] COPEN = {50000, 63000}; /* Fixed cost of factory f being open for one period */ static final double CPSTOCK = 2.0; /* Unit cost to store any product p */ static final double CRSTOCK = 1.0; /* Unit cost to store any raw material r */ static final double[][] REQ = { {1.0, 0.5}, {1.3, 0.4} }; /* Requirement by unit of prod. p for raw material r */ static final double[][] MXSELL = { {650, 600, 500, 400}, {600, 500, 300, 250} }; /* Max. amount of p that can be sold in period t */ static final double[] MXMAKE = {400, 500}; /* Max. amount factory f can make over all products */ static final double MXRSTOCK = 300; /* Max. amount of r that can be stored each f and t */ static final double[][] PSTOCK0 = { {50, 100}, {50, 50} }; /* Initial product p stock level at factory f */ static final double[][] RSTOCK0 = { {100, 150}, {50, 100} }; /* Initial raw material r stock level at factory f*/ /***********************************************************************/ public static void main(String[] args) { try (XPRBprob pb = new XPRBprob("Coco"); /* Initialize BCL and create a new problem */ XPRBexprContext context = new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) { XPRBvar[][][] make, sell, pstock, buy, rstock; XPRBvar[][] openm; XPRBexpr lobj, lc; int p, f, r, t; /****VARIABLES****/ make = new XPRBvar[NP][NF][NT]; sell = new XPRBvar[NP][NF][NT]; pstock = new XPRBvar[NP][NF][NT + 1]; buy = new XPRBvar[NR][NF][NT]; rstock = new XPRBvar[NR][NF][NT + 1]; openm = new XPRBvar[NF][NT]; for (p = 0; p < NP; p++) for (f = 0; f < NF; f++) { for (t = 0; t < NT; t++) { make[p][f][t] = pb.newVar("make_p" + (p + 1) + "_f" + (f + 1)); /* Amount of prod. p to make at factory f in period t */ sell[p][f][t] = pb.newVar("sell_p" + (p + 1) + "_f" + (f + 1)); /* Amount of prod. p sold from factory f in period t */ } for (t = 0; t < NT + 1; t++) pstock[p][f][t] = pb.newVar("pstock_p" + (p + 1) + "_f" + (f + 1)); /* Stock level of prod. p at factory f at start of period t */ } for (r = 0; r < NR; r++) for (f = 0; f < NF; f++) { for (t = 0; t < NT; t++) buy[r][f][t] = pb.newVar("buy_r" + (r + 1) + "_f" + (f + 1)); /* Amount of raw material r bought for factory f in period t */ for (t = 0; t < NT + 1; t++) rstock[r][f][t] = pb.newVar("rstock_r" + (r + 1) + "_f" + (f + 1)); /* Stock level of raw mat. r at factory f at start of per. t */ } for (f = 0; f < NF; f++) for (t = 0; t < NT; t++) openm[f][t] = pb.newVar("open_f" + (f + 1), XPRB.BV); /* 1 if factory f is open in period t, else 0 */ /****OBJECTIVE****/ lobj = new XPRBexpr(); for (f = 0; f < NF; f++) { /* Objective: maximize total profit */ for (p = 0; p < NP; p++) { for (t = 0; t < NT; t++) lobj.add(sell[p][f][t].mul(REV[p][t])).add(make[p][f][t].mul(-CMAK[p][f])); for (t = 1; t < NT + 1; t++) lobj.add(pstock[p][f][t].mul(-CPSTOCK)); } if (PHASE == 4) for (t = 0; t < NT; t++) lobj.add(openm[f][t].mul(20000 - COPEN[f])); else if (PHASE == 5) for (t = 0; t < NT; t++) lobj.add(openm[f][t].mul(-COPEN[f])); for (r = 0; r < NR; r++) { for (t = 0; t < NT; t++) lobj.add(buy[r][f][t].mul(-CBUY[r][t])); for (t = 1; t < NT + 1; t++) lobj.add(rstock[r][f][t].mul(-CRSTOCK)); } } pb.setObj(lobj); /* Set objective function */ /****CONSTRAINTS****/ for (p = 0; p < NP; p++) /* Product stock balance */ for (f = 0; f < NF; f++) for (t = 0; t < NT; t++) pb.newCtr( "PBal", pstock[p][f][t].add(make[p][f][t]).eql(sell[p][f][t].add(pstock[p][f][t + 1]))); for (r = 0; r < NR; r++) /* Raw material stock balance */ for (f = 0; f < NF; f++) for (t = 0; t < NT; t++) { lc = new XPRBexpr(); for (p = 0; p < NP; p++) lc.add(make[p][f][t].mul(REQ[p][r])); pb.newCtr("RBal", rstock[r][f][t].add(buy[r][f][t]).eql(lc.add(rstock[r][f][t + 1]))); } for (p = 0; p < NP; p++) for (t = 0; t < NT; t++) { /* Limit on the amount of product p to be sold */ lc = new XPRBexpr(); for (f = 0; f < NF; f++) lc.add(sell[p][f][t]); pb.newCtr("MxSell", lc.lEql(MXSELL[p][t])); } for (f = 0; f < NF; f++) for (t = 0; t < NT; t++) { /* Capacity limit at factory f */ lc = new XPRBexpr(); for (p = 0; p < NP; p++) lc.add(make[p][f][t]); pb.newCtr("MxMake", lc.lEql(openm[f][t].mul(MXMAKE[f]))); } for (f = 0; f < NF; f++) for (t = 1; t < NT + 1; t++) { /* Raw material stock limit */ lc = new XPRBexpr(); for (r = 0; r < NR; r++) lc.add(rstock[r][f][t]); pb.newCtr("MxRStock", lc.lEql(MXRSTOCK)); } if (PHASE == 5) for (f = 0; f < NF; f++) for (t = 0; t < NT - 1; t++) /* Once closed, always closed */ pb.newCtr("Closed", openm[f][t + 1].lEql(openm[f][t])); /****BOUNDS****/ for (p = 0; p < NP; p++) for (f = 0; f < NF; f++) pstock[p][f][0].fix(PSTOCK0[p][f]); /* Initial product levels */ for (r = 0; r < NR; r++) for (f = 0; f < NF; f++) rstock[r][f][0].fix(RSTOCK0[r][f]); /* Initial raw mat. levels */ if (PHASE <= 3) for (f = 0; f < NF; f++) for (t = 0; t < NT; t++) openm[f][t].fix(1); /****SOLVING + OUTPUT****/ pb.setSense(XPRB.MAXIM); /* Choose the sense of the optimization */ pb.mipOptimize(""); /* Solve the MIP-problem */ System.out.println("Objective: " + pb.getObjVal()); /* Get objective value */ /* Uncomment to print out the solution values */ /* for(p=0;p<NP;p++) for(f=0;f<NF;f++) for(t=0;t<NT;t++) System.out.print(make[p][f][t].getName() + ":" + make[p][f][t].getSol() + " " + sell[p][f][t].getName() +":" + sell[p][f][t].getSol()); System.out.println(); for(p=0;p<NP;p++) for(f=0;f<NF;f++) for(t=0;t<NT+1;t++) System.out.print(pstock[p][f][t].getName() +":" + pstock[p][f][t].getSol() + " "); System.out.println(); for(r=0;r<NR;r++) for(f=0;f<NF;f++) { for(t=0;t<NT;t++) System.out.print(buy[r][f][t].getName() +":" + buy[r][f][t].getSol() + " "); for(t=0;t<NT+1;t++) System.out.print(rstock[r][f][t].getName() +":" + rstock[r][f][t].getSol() + " "); } for(f=0;f<NF;f++) for(t=0;t<NT;t++) System.out.print(openm[f][t].getName() +":" + openm[f][t].getSol() + " "); System.out.println(); */ } } } | |||||||||||||||||
© Copyright 2024 Fair Isaac Corporation. |