| |||||||||||||||||||||||||
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.cs /******************************************************** Xpress-BCL C# Example Problems ============================== file xbcoco3.cs ```````````````` Coco Problem Phase 3. Introduce time periods and inventory. (c) 2008-2024 Fair Isaac Corporation authors: S.Heipcke, D.Brett. ********************************************************/ using System; using System.Text; using System.IO; using BCL; namespace Examples { public class TestCoco3 { const int NP = 2; /* Number of products (p) */ const int NF = 2; /* Factories (f) */ const int NR = 2; /* Raw materials (r) */ const int NT = 4; /* Time periods (t) */ //Define XPRBDATAPATH to wherever you have placed the data folder; here we expect it to be same directory as compiled example. static string XPRBDATAPATH = Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).FullName + "/Data"; static string PSTOCK0FILE= XPRBDATAPATH + "/coco/pstock0.dat"; static string RSTOCK0FILE= XPRBDATAPATH + "/coco/rstock0.dat"; static string REVFILE = XPRBDATAPATH + "/coco/revt.dat"; static string CMAKEFILE = XPRBDATAPATH + "/coco/cmake.dat"; static string CBUYFILE = XPRBDATAPATH + "/coco/cbuyt.dat"; static string REQFILE = XPRBDATAPATH + "/coco/req.dat"; static string MXSELLFILE = XPRBDATAPATH + "/coco/maxsellt.dat"; static string MXMAKEFILE = XPRBDATAPATH + "/coco/mxmake.dat"; /****TABLES****/ double[,] REV = new double[NP,NT]; /* Unit selling price of product p in period t */ double[,] CMAK = new double[NP,NF]; /* Unit cost to make product p at factory f */ double[,] CBUY = new double[NR,NT]; /* Unit cost to buy raw material r in period t */ double[,] REQ = new double[NP,NR]; /* Requirement by unit of prod. p for raw material r */ double[,] MXSELL = new double[NP,NT]; /* Max. amount of p that can be sold in period t */ double[] MXMAKE = new double[NF]; /* Max. amount factory f can make over all products */ double[,] PSTOCK0 = new double[NP,NF]; /* Initial product p stock level at factory f */ double[,] RSTOCK0 = new double[NR,NF]; /* Initial raw material r stock level at factory f*/ /****DATA****/ double CPSTOCK = 2.0; /* Unit cost to store any product p */ double CRSTOCK = 1.0; /* Unit cost to store any raw material r */ double MXRSTOCK = 300; /* Max. amount of r that can be stored each f and t */ XPRBprob pb = new XPRBprob("Coco3"); /* Initialize a new problem in BCL */ /***********************************************************************/ void modCoco3() { XPRBvar[,,] make = new XPRBvar[NP,NF,NT]; XPRBvar[,,] sell = new XPRBvar[NP,NF,NT]; XPRBvar[,,] pstock = new XPRBvar[NP,NF,NT+1]; XPRBvar[,,] buy = new XPRBvar[NR,NF,NT]; XPRBvar[,,] rstock = new XPRBvar[NR,NF,NT+1]; XPRBexpr lobj, lc; int p,f,r,t; /****VARIABLES****/ 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 += REV[p,t]*sell[p,f,t] - CMAK[p,f]*make[p,f,t]; for(t=1;t<NT+1;t++) lobj -= CPSTOCK*pstock[p,f,t]; } for(r=0;r<NR;r++) { for(t=0;t<NT;t++) lobj -= CBUY[r,t]*buy[r,f,t]; for(t=1;t<NT+1;t++) lobj -= CRSTOCK*rstock[r,f,t]; } } pb.setObj(pb.newCtr("OBJ",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]+make[p,f,t] == sell[p,f,t]+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(0); for(p=0;p<NP;p++) lc += REQ[p,r]*make[p,f,t]; pb.newCtr("RBal", rstock[r,f,t]+buy[r,f,t] == lc+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(0); for(f=0;f<NF;f++) lc += sell[p,f,t]; pb.newCtr("MxSell", lc <= MXSELL[p,t]); } for(f=0;f<NF;f++) for(t=0;t<NT;t++) { /* Capacity limit at factory f */ lc = new XPRBexpr(0); for(p=0;p<NP;p++) lc += make[p,f,t]; pb.newCtr("MxMake", lc <= MXMAKE[f]); } for(f=0;f<NF;f++) for(t=1;t<NT+1;t++) { /* Raw material stock limit */ lc = new XPRBexpr(0); for(r=0;r<NR;r++) lc += rstock[r,f,t]; pb.newCtr("MxRStock", lc <= 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(BCLconstant.XPRB_MAXIM); /* Choose the sense of the optimization */ pb.lpOptimize(); /* Solve the LP-problem */ System.Console.WriteLine("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.Console.Write(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.Console.Write(pstock[p,f,t].getName() + ":" + pstock[p,f,t].getSol() + " "); } System.Console.WriteLine(); for(r=0;r<NR;r++) for(f=0;f<NF;f++) { for(t=0;t<NT;t++) System.Console.Write(buy[r,f,t].getName() + ":" + buy[r,f,t].getSol() + " "); for(t=0;t<NT+1;t++) System.Console.Write(rstock[r,f,t].getName() + ":" + rstock[r,f,t].getSol() + " "); } System.Console.WriteLine(); */ } /***********************************************************************/ /**** Read data from files ****/ void readData() { FileStream file; StreamReader fileStreamIn; int p, r; /* Read the revenu data file */ file = new FileStream(REVFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (p = 0; p < NP; p++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NT); for (int q = 0; q < NT; q++) REV[p, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the production cost data file */ file = new FileStream(CMAKEFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (p = 0; p < NP; p++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NF); for (int q = 0; q < NF; q++) CMAK[p, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the raw material cost data file */ file = new FileStream(CBUYFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (r = 0; r < NR; r++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NT); for (int q = 0; q < NT; q++) CBUY[r, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the resource requirement data file */ file = new FileStream(REQFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (p = 0; p < NP; p++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NR); for (int q = 0; q < NR; q++) REQ[p, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the max. sales quantities data file */ file = new FileStream(MXSELLFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (p = 0; p < NP; p++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NT); for (int q = 0; q < NT; q++) MXSELL[p, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the production capacities data file */ file = new FileStream(MXMAKEFILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out MXMAKE, NF); fileStreamIn.Close(); file.Close(); /* Read the product stock data file */ /* Read the max. sales quantities data file */ file = new FileStream(PSTOCK0FILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (p = 0; p < NP; p++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NF); for (int q = 0; q < NF; q++) PSTOCK0[p, q] = temp[q]; } fileStreamIn.Close(); file.Close(); /* Read the raw material stock data file */ file = new FileStream(RSTOCK0FILE, FileMode.Open, FileAccess.Read); fileStreamIn = new StreamReader(file); for (r = 0; r < NR; r++) { double[] temp = new double[NF]; pb.XPRBreadarrline(fileStreamIn, 200, "{g} , ", out temp, NF); for (int q = 0; q < NF; q++) RSTOCK0[r, q] = temp[q]; } fileStreamIn.Close(); file.Close(); } /***********************************************************************/ public static void Main() { XPRB.init(); TestCoco3 TestInstance = new TestCoco3(); TestInstance.readData(); /* Data input from file */ TestInstance.modCoco3(); /* Model and solve the problem */ return; } } } | |||||||||||||||||||||||||
© Copyright 2024 Fair Isaac Corporation. |