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) {
        XPRB bcl;
        XPRBvar[][][] make, sell, pstock, buy, rstock;
        XPRBvar[][] openm;
        XPRBexpr lobj, lc;
        int p,f,r,t;

        try (XPRBprob pb = new XPRBprob("Coco")) { /* Initialize BCL and create a new problem */

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