| |||||||||||||||||
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.cxx /******************************************************** Xpress-BCL C++ Example Problems =============================== file xbcoco.cxx ``````````````` 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 ********************************************************/ #include <iostream> #include "xprb_cpp.h" using namespace std; using namespace ::dashoptimization; #define 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 */ #define NP 2 /* Number of products (p) */ #define NF 2 /* factories (f) */ #define NR 2 /* raw materials (r) */ #define NT 4 /* time periods (t) */ /****DATA****/ double REV[][NT] = /* Unit selling price of product p in period t */ {{400, 380, 405, 350}, {410, 397, 412, 397}}; double CMAK[][NF] = /* Unit cost to make product p at factory f */ {{150, 153}, { 75, 68}}; double CBUY[][NT] = /* Unit cost to buy raw material r in period t */ {{100, 98, 97, 100}, {200, 195, 198, 200}}; double COPEN[] = /* Fixed cost of factory f being open for one period */ {50000, 63000}; double CPSTOCK = 2.0; /* Unit cost to store any product p */ double CRSTOCK = 1.0; /* Unit cost to store any raw material r */ double REQ[][NR] = /* Requirement by unit of prod. p for raw material r */ {{1.0, 0.5}, {1.3, 0.4}}; double MXSELL[][NT] = /* Max. amount of p that can be sold in period t */ {{650, 600, 500, 400}, {600, 500, 300, 250}}; double MXMAKE[] = /* Max. amount factory f can make over all products */ {400, 500}; double MXRSTOCK = 300; /* Max. amount of r that can be stored each f and t */ double PSTOCK0[][NF] = /* Initial product p stock level at factory f */ {{50, 100}, {50, 50}}; double RSTOCK0[][NF] = /* Initial raw material r stock level at factory f*/ {{100, 150}, { 50, 100}}; /***********************************************************************/ int main(int argc, char **argv) { XPRBvar make[NP][NF][NT], sell[NP][NF][NT], pstock[NP][NF][NT+1], buy[NR][NF][NT], rstock[NR][NF][NT+1], openm[NF][NT]; XPRBexpr lobj, lc; int p,f,r,t; XPRBprob pb("Coco"); /* Initialize a new problem in BCL */ /****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(XPRBnewname("make_p%d_f%d",p+1,f+1)); /* Amount of prod. p to make at factory f in period t */ sell[p][f][t] = pb.newVar(XPRBnewname("sell_p%d_f%d",p+1,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(XPRBnewname("pstock_p%d_f%d",p+1,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(XPRBnewname("buy_r%d_f%d",r+1,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(XPRBnewname("rstock_r%d_f%d",r+1,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(XPRBnewname("open_f%d",f+1), XPRB_BV); /* 1 if factory f is open in period t, else 0 */ /****OBJECTIVE****/ 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]; } if(PHASE==4) for(t=0;t<NT;t++) lobj += (20000-COPEN[f])*openm[f][t]; else if(PHASE==5) for(t=0;t<NT;t++) lobj -= COPEN[f]*openm[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=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=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=0; for(p=0;p<NP;p++) lc += make[p][f][t]; pb.newCtr("MxMake", lc <= MXMAKE[f]*openm[f][t]); } for(f=0;f<NF;f++) for(t=1;t<NT+1;t++) { /* Raw material stock limit */ lc=0; for(r=0;r<NR;r++) lc += rstock[r][f][t]; pb.newCtr("MxRStock", lc <= 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] <= 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 */ cout << "Objective: " << pb.getObjVal() << endl; /* 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++) cout << make[p][f][t].getName() << ":" << make[p][f][t].getSol() << " " << sell[p][f][t].getName() << ":" << sell[p][f][t].getSol()) << " "; cout << endl; for(p=0;p<NP;p++) for(f=0;f<NF;f++) for(t=0;t<NT+1;t++) cout << pstock[p][f][t].getName() << ":" << pstock[p][f][t].getSol() << " "; cout << endl; for(r=0;r<NR;r++) for(f=0;f<NF;f++) { for(t=0;t<NT;t++) cout << buy[r][f][t].getName() << ":" << buy[r][f][t].getSol() << " "; for(t=0;t<NT+1;t++) cout << rstock[r][f][t].getName() << ":" << rstock[r][f][t].getSol() << " "; } for(f=0;f<NF;f++) for(t=0;t<NT;t++) cout << openm[f][t].getName() << ":" << openm[f][t].getSol() << " "; cout << endl; */ return 0; } | |||||||||||||||||
© Copyright 2024 Fair Isaac Corporation. |