| |||||||||||||||||
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 xbcoco3.java /******************************************************** * Xpress-BCL Java Example Problems * ================================ * * file xbcoco3.java * ````````````````` * Coco Problem Phase 3. * Introduce time periods and inventory. * * (c) 2008-2024 Fair Isaac Corporation * author: S.Heipcke, Jan. 2000, rev. Mar. 2011 ********************************************************/ import com.dashoptimization.*; import java.io.*; public class xbcoco3 { 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) */ static final String REVFILE = System.getProperty("XPRBDATA") + "/coco/revt.dat"; static final String CMAKEFILE = System.getProperty("XPRBDATA") + "/coco/cmake.dat"; static final String CBUYFILE = System.getProperty("XPRBDATA") + "/coco/cbuyt.dat"; static final String REQFILE = System.getProperty("XPRBDATA") + "/coco/req.dat"; static final String MXSELLFILE = System.getProperty("XPRBDATA") + "/coco/maxsellt.dat"; static final String MXMAKEFILE = System.getProperty("XPRBDATA") + "/coco/mxmake.dat"; static final String PSTOCK0FILE = System.getProperty("XPRBDATA") + "/coco/pstock0.dat"; static final String RSTOCK0FILE = System.getProperty("XPRBDATA") + "/coco/rstock0.dat"; /****TABLES****/ static double[][] REV; /* Unit selling price of product p in period t */ static double[][] CMAK; /* Unit cost to make product p at factory f */ static double[][] CBUY; /* Unit cost to buy raw material r in period t */ static double[][] REQ; /* Requirement by unit of prod. p for raw mat. r */ static double[][] MXSELL; /* Max. amount of p that can be sold in period t */ static double[] MXMAKE; /* Max. amount factory f can make over all prod.s */ static double[][] PSTOCK0; /* Initial product p stock level at factory f */ static double[][] RSTOCK0; /* Initial raw material r stock level at factory f*/ /****DATA****/ 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 mat. r */ static final double MXRSTOCK = 300; /* Max. amount of r that can be stored each f and t */ /***********************************************************************/ static void modCoco3() { try (XPRBprob pb = new XPRBprob("Coco3"); /* Initialize BCL and create a new problem */ XPRBexprContext context = new XPRBexprContext() /* Release XPRBexpr instances at end of block. */) { XPRBvar[][][] make, sell, pstock, buy, rstock; 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]; 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 */ } /****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)); } 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(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)); } /****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 */ /****SOLVING + OUTPUT****/ pb.setSense(XPRB.MAXIM); /* Choose the sense of the optimization */ pb.lpOptimize(""); /* Solve the LP-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()); 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() + " "); } 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 single line data file ****/ static void readOneLineFile(String filename, double[] data) throws IOException { FileReader datafile = null; StreamTokenizer st; int i = 0; datafile = new FileReader(filename); st = initST(datafile); do { do { st.nextToken(); } while (st.ttype == st.TT_EOL); /* Skip empty lines */ while (st.ttype == st.TT_NUMBER) { data[i++] = st.nval; if (st.nextToken() != ',') break; st.nextToken(); } } while (st.ttype == st.TT_EOL); datafile.close(); } /**** Read multi line data file ****/ static void readMultiLineFile(String filename, double[][] data) throws IOException { FileReader datafile = null; StreamTokenizer st; int i = 0, j = 0; datafile = new FileReader(filename); st = initST(datafile); do { do { st.nextToken(); } while (st.ttype == st.TT_EOL); /* Skip empty lines */ while (st.ttype == st.TT_NUMBER) { data[j][i++] = st.nval; if (st.nextToken() != ',') { j++; i = 0; break; } st.nextToken(); } } while (st.ttype == st.TT_EOL); datafile.close(); } /**** Read data from files ****/ static void readData() throws IOException { int p, r; REV = new double[NP][NT]; CMAK = new double[NP][NF]; CBUY = new double[NR][NT]; REQ = new double[NP][NR]; MXSELL = new double[NP][NT]; MXMAKE = new double[NF]; PSTOCK0 = new double[NP][NF]; RSTOCK0 = new double[NR][NF]; /* Read the revenu data file */ readMultiLineFile(REVFILE, REV); /* Read the production cost data file */ readMultiLineFile(CMAKEFILE, CMAK); /* Read the raw material cost data file */ readMultiLineFile(CBUYFILE, CBUY); /* Read the resource requirement data file */ readMultiLineFile(REQFILE, REQ); /* Read the max. sales quantities data file */ readMultiLineFile(MXSELLFILE, MXSELL); /* Read the production capacities data file */ readOneLineFile(MXMAKEFILE, MXMAKE); /* Read the product stock data file */ readMultiLineFile(PSTOCK0FILE, PSTOCK0); /* Read the raw material stock data file */ readMultiLineFile(RSTOCK0FILE, RSTOCK0); } /***********************************************************************/ public static void main(String[] args) { try { readData(); /* Data input from file */ } catch (IOException e) { System.err.println(e.getMessage()); System.exit(1); } modCoco3(); /* Model and solve the problem */ } } | |||||||||||||||||
© Copyright 2024 Fair Isaac Corporation. |