FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

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.
  1. xbcoco1: initial formulation, data, variables and constraints fixed
  2. xbcoco2: use parameters, data tables and subscripted variables.

    read data tables in from text data files (short-term planning).
  3. xbcoco3: like xbcoco2.c, but several time periods (mid-term planning).
  4. xbcoco : complete problem, data defined in the model definition (long-term planning).

xbcocojava.zip[download all files]

Source Files

Data Files





xbcoco3.java

/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcoco3.java
  `````````````````
  Coco Problem Phase 3. 
  Introduce time periods and inventory.

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Mar. 2011
********************************************************/

import java.io.*;
import com.dashoptimization.*;

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 XPRBprob pb;

/***********************************************************************/

 static void modCoco3()
 {
  XPRB bcl;
  XPRBvar[][][] make, sell, pstock, buy, rstock;
  XPRBexpr lobj, lc;
  int p,f,r,t;
 
  bcl = new XPRB();                   /* Initialize BCL */
  pb = bcl.newProb("Coco3");          /* Create a new problem in BCL */

/****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 */
 }
} 

Back to examples browserPrevious exampleNext example