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
By clicking on a file name, a preview is opened at the bottom of this page.
xbcoco1.java[download]
xbcoco2.java[download]
xbcoco3.java[download]
xbcoco.java[download]

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();
      */
    }
  }
}

Back to examples browserPrevious exampleNext example