Initializing help system before first use

Coco - A full production planning example


Type: Production planning
Rating: 2 (easy-medium)
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).
File(s): xbcoco1.java, xbcoco2.java, xbcoco3.java, xbcoco.java
Data file(s): rev.dat, cmake.dat, cbuy.dat, req.dat, maxsell.dat, mxmake.dat, revt.dat, cbuyt.dat, maxsellt.dat, pstock0.dat, rstock0.dat


xbcoco1.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcoco1.java
  `````````````````
  Coco Problem Phase 1.
  Initial formulation: data, variables and constraints fixed.

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


import com.dashoptimization.*;

public class xbcoco1 {
    public static void main(String[] args) {
        XPRBvar make11,make21,make12,make22;

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

            /****VARIABLES****/
            make11 = p.newVar("make11"); /* Amount of prod. 1 to make at factory 1 */
            make21 = p.newVar("make21"); /* Amount of prod. 2 to make at factory 1 */
            make12 = p.newVar("make12"); /* Amount of prod. 1 to make at factory 2 */
            make22 = p.newVar("make22"); /* Amount of prod. 2 to make at factory 2 */

            /****OBJECTIVE****/
            /* Define & set objective function: maximize total profit */
            p.setObj(make11.mul(50).add(make21.mul(125)).add(make12.mul(47))
                     .add(make22.mul(132)) );

            /****CONSTRAINTS****/
            p.newCtr("MxMake1", make11.add(make21).lEql(400) );
            /* Capacity limit at factory 1 */

            p.newCtr("MxMake2", make12.add(make22).lEql(500) );
            /* Capacity limit at factory 2 */

            p.newCtr("MxSell1", make11.add(make12).lEql(650) );
            /* Limit on the amount of prod. 1 to be sold */

            p.newCtr("MxSell2", make21.add(make22).lEql(600) );
            /* Limit on the amount of prod. 2 to be sold */

            /****SOLVING + OUTPUT****/
            p.setSense(XPRB.MAXIM);      /* Choose the sense of the optimization */
            p.lpOptimize("");            /* Solve the LP-problem */
            System.out.println("Objective: " + p.getObjVal());  /* Get objective value */

            /* Print out the solution values for all variables */
            System.out.println(make11.getName() +": " + make11.getSol());
            System.out.println(make21.getName() +": " + make21.getSol());
            System.out.println(make12.getName() +": " + make12.getSol());
            System.out.println(make22.getName() +": " + make22.getSol());
        }
    }
}

xbcoco2.java
/********************************************************
  Xpress-BCL Java Example Problems
  ================================

  file xbcoco2.java
  `````````````````
  Coco Problem Phase 2.
  Use parameters, data tables and subscripted variables
  to separate the model structure from the data.
  Read data tables in from text data files.

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

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

public class xbcoco2 {
    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 String REVFILE   = System.getProperty("XPRBDATA") +
        "/coco/rev.dat";
    static final String CMAKEFILE = System.getProperty("XPRBDATA") +
        "/coco/cmake.dat";
    static final String CBUYFILE  = System.getProperty("XPRBDATA") +
        "/coco/cbuy.dat";
    static final String REQFILE   = System.getProperty("XPRBDATA") +
        "/coco/req.dat";
    static final String MXSELLFILE= System.getProperty("XPRBDATA") +
        "/coco/maxsell.dat";
    static final String MXMAKEFILE= System.getProperty("XPRBDATA") +
        "/coco/mxmake.dat";

    /****TABLES****/
    static double[] REV;       /* Unit selling price of product p */
    static double[][] CMAK;    /* Unit cost to make product p at factory f */
    static double[] CBUY;      /* Unit cost to buy raw material r */
    static double[][] REQ;     /* Requirement by unit of prod. p for raw mat. r */
    static double[] MXSELL;    /* Max. amount of p that can be sold */
    static double[] MXMAKE;    /* Max. amount factory f can make over all prod.s */
    static double[][] PROFIT;  /* Profit contribution of product p at factory f */

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

    static void modCoco2() {
        XPRBvar[][] make;
        XPRBexpr lobj, lc;
        int p,f;

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

            /****VARIABLES****/
            make = new XPRBvar[NP][NF];
            for(p=0;p<NP;p++)         /* Amount of prod. p to make at factory f */
                for(f=0;f<NF;f++)
                    make[p][f] = pb.newVar("make_"+ (p+1) +"f"+ (f+1));

            /****OBJECTIVE****/
            lobj = new XPRBexpr();
            for(p=0;p<NP;p++)         /* Objective: maximize total profit */
                for(f=0;f<NF;f++)  lobj.add(make[p][f].mul(PROFIT[p][f]));
            pb.setObj(lobj);

            /****CONSTRAINTS****/

            for(p=0;p<NP;p++) {          /* Limit on the amount of product p to be sold */
                lc = new XPRBexpr();
                for(f=0;f<NF;f++)  lc .add(make[p][f]);
                pb.newCtr("MxSell", lc.lEql(MXSELL[p]) );
            }

            for(f=0;f<NF;f++) {          /* Capacity limit at factory f */
                lc = new XPRBexpr();
                for(p=0;p<NP;p++) lc.add(make[p][f]);
                pb.newCtr("MxMake", lc.lEql(MXMAKE[f]) );
            }

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

            for(p=0;p<NP;p++)         /* Print the solution values */
                for(f=0;f<NF;f++)
                    System.out.print(make[p][f].getName()+ ":"+ make[p][f].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,f,r;

        REV = new double[NP];
        CMAK = new double[NP][NF];
        CBUY = new double[NR];
        REQ = new double[NP][NR];
        MXSELL = new double[NP];
        MXMAKE = new double[NF];
        PROFIT = new double[NP][NF];

        /* Read the revenu data file */
        readOneLineFile(REVFILE,REV);

        /* Read the production cost data file */
        readMultiLineFile(CMAKEFILE,CMAK);

        /* Read the raw material cost data file */
        readOneLineFile(CBUYFILE,CBUY);

        /* Read the resource requirement data file */
        readMultiLineFile(REQFILE,REQ);

        /* Read the max. sales quantities data file */
        readOneLineFile(MXSELLFILE,MXSELL);

        /* Read the production capacities data file */
        readOneLineFile(MXMAKEFILE,MXMAKE);

        /* Calculate the table PROFIT */
        for(p=0;p<NP;p++)
            for(f=0;f<NF;f++) {
                PROFIT[p][f] = REV[p] - CMAK[p][f];
                for(r=0;r<NR;r++) PROFIT[p][f] -= (REQ[p][r]*CBUY[r]);
            }
    }

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

    public static void main(String[] args) {
        try {
            readData();           /* Data input from file */
        }
        catch(IOException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        modCoco2();            /* Model and solve the problem */
    }
}

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

        try (XPRBprob pb = new XPRBprob("Coco3")) { /* 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];
            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 */
    }
}

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

© 2001-2022 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.