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

UG - Examples from 'BCL Reference Manual'

Description
The following examples are discussed in detail in the 'BCL User Guide and Reference Manual':
  • modeling and solving a small MIP scheduling problem (xbexpl1 version BASIC)
  • using variable arrays and constraint templates (xbexpl1 versions ARRAY and ARRAYC)
  • definition of SOS-1 (xbexpl1 version SOS)
  • data input from file, index sets (xbexpl1i)
  • user error handling, output redirection (xbexpl3)
  • solving multiple scenarios of a transportation problem in parallel (xbexpl2: standard, single thread version)
  • cut generation / adding cuts at MIP tree nodes (xbcutex)
  • quadratic programming (quadratic objective: xbqpr12, quadratic constraints: xbairport)
  • combine BCL problem input with problem solving in Xpress Optimizer (xbcontr1)
  • use an Xpress Optimizer solution callback with a BCL model (xbcontr2s: single MIP thread; xbcontr2: multiple MIP threads)
Further explanation of this example: 'BCL Reference Manual', Appendix B Using BCL with the Optimizer library


Source Files

Data Files





xbexpl1.cs

/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbexpl1.cs
  ```````````````
  BCL user guide example.
  Definition of variables and constraints,
  variable arrays and SOS, followed by file output,
  solving and printing of solutions.

  (c) 2008-2024 Fair Isaac Corporation
      authors: S.Heipcke, D.Brett.
********************************************************/

using System;
using System.Text;
using System.IO;
using BCL;


namespace Examples
{

    public class TestUGExpl1
    {
        const int NJ  =  4;             /* Number of jobs */
        const int NT  = 10;             /* Time limit */

        bool SOS = false;

        /**** DATA ****/
        double[] DUR = {3,4,2,2};   /* Durations of jobs   */

        XPRBvar[] start = new XPRBvar[NJ];          /* Start times of jobs  */
        XPRBvar[,] delta = new XPRBvar[NJ,NT];      /* Binaries for start times */
        XPRBvar z;                  /* Maximum completion time (makespan) */
        XPRBsos[] set = new XPRBsos[NJ];            /* Sets regrouping start times for jobs */

        XPRBprob p = new XPRBprob("Jobs");         /* Initialize BCL and a new problem */

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

        public void jobsModel()
        {
            XPRBexpr le;
            int j,t;

            /****VARIABLES****/
            /* Create start time variables */
            for(j=0;j<NJ;j++) start[j] = p.newVar("start");
            z = p.newVar("z",BCLconstant.XPRB_PL,0,NT);  /* Declare the makespan variable */

            for(j=0;j<NJ;j++)              /* Declare binaries for each job  */
                for(t=0;t<(NT-DUR[j]+1);t++)
                    delta[j,t] = p.newVar("delta" + (j+1) + (t+1),BCLconstant.XPRB_BV);

            /****CONSTRAINTS****/
            for(j=0;j<NJ;j++)              /* Calculate maximal completion time */
                p.newCtr("Makespan", start[j]+DUR[j] <= z);

            p.newCtr("Prec", start[0]+DUR[0] <= start[2]);
            /* Precedence relation between jobs  */

            for(j=0;j<NJ;j++)              /* Linking start times and binaries  */
            {
                le = new XPRBexpr(0);
                for(t=0;t<(NT-DUR[j]+1);t++)  le += (t+1)*delta[j,t];
                p.newCtr("Link_" + (j+1), le == start[j]);
            }

            for(j=0;j<NJ;j++)              /* One unique start time for each job  */
            {
                le = new XPRBexpr(0);
                for(t=0;t<(NT-DUR[j]+1);t++)  le += delta[j,t];
                p.newCtr("One_" + (j+1), le == 1);
            }

            /****OBJECTIVE****/
            p.setObj(p.newCtr("OBJ", new XPRBrelation(z)));  /* Define and set objective function */

            /****BOUNDS****/
            for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1);
            /* Upper bounds on start time variables */

            /****OUTPUT****/
            p.print();                     /* Print out the problem definition */
            p.exportProb(BCLconstant.XPRB_MPS,"expl1");  /* Output matrix to MPS file */
        }

        /*************************************************************************/
        public void jobsSolve()
        {
            int j,t,statmip;

            if(SOS)
            {
                for(j=0;j<NJ;j++)
                    for(t=0;t<NT-DUR[j]+1;t++)
                        delta[j,t].setDir(BCLconstant.XPRB_PR,10*(t+1));
                        /* Give highest priority to variables for earlier start times */
            }
            else
            {
                for(j=0;j<NJ;j++)
                    set[j].setDir(BCLconstant.XPRB_DN);       /* First branch downwards on sets */
            }

            p.setSense(BCLconstant.XPRB_MINIM);
            p.mipOptimize();                   /* Solve the problem as MIP */
            statmip = p.getMIPStat();       /* Get the MIP problem status */

            if((statmip == BCLconstant.XPRB_MIP_SOLUTION) || (statmip == BCLconstant.XPRB_MIP_OPTIMAL))
            /* An integer solution has been found */
            {
                System.Console.WriteLine("Objective: " + p.getObjVal());
                for(j=0;j<NJ;j++)
                {                              /* Print the solution for all start times */
                    System.Console.WriteLine(start[j].getName() + ": " + start[j].getSol());
                    for(t=0;t<NT-DUR[j]+1;t++)
                        System.Console.Write(delta[j,t].getName() + ": " + delta[j,t].getSol() + " ");
                    System.Console.WriteLine();
                }
            }
        }

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

        public static void Main()
        {
           XPRB.init();
           TestUGExpl1 TestInstance = new TestUGExpl1();

            if (TestInstance.SOS)
                TestInstance.jobsModel();                   /* Basic problem definition */
            else
                TestInstance.jobsModelb();                  /* Formulation using SOS */

            TestInstance.jobsSolve();                   /* Solve and print solution */

            return;
        }

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

        public void jobsModelb()         /**** SOS-formulation ****/
        {
            XPRBexpr le;
            int j,t;

            /****VARIABLES****/
            /* Create start time variables */
            for(j=0;j<NJ;j++) start[j] = p.newVar("start");
                z = p.newVar("z",BCLconstant.XPRB_PL,0,NT);  /* Declare the makespan variable */

            for(j=0;j<NJ;j++)              /* Declare binaries for each job */
                for(t=0;t<(NT-DUR[j]+1);t++)
                    delta[j,t] = p.newVar("delta" + (j+1) + (t+1),BCLconstant.XPRB_PL,0,1);

            /****CONSTRAINTS****/
            for(j=0;j<NJ;j++)              /* Calculate maximal completion time */
                p.newCtr("Makespan", start[j]+DUR[j] <= z);

            p.newCtr("Prec", start[0]+DUR[0] <= start[2]);
            /* Precedence relation between jobs */

            for(j=0;j<NJ;j++)              /* Linking start times and binaries */
            {
                le = new XPRBexpr(0);
                for(t=0;t<(NT-DUR[j]+1);t++)  le += (t+1)*delta[j,t];
                p.newCtr("Link_" + (j+1), le == start[j]);
            }

            for(j=0;j<NJ;j++)              /* One unique start time for each job */
            {
                le = new XPRBexpr(0);
                for(t=0;t<(NT-DUR[j]+1);t++)  le += delta[j,t];
                p.newCtr("One_" + (j+1), le == 1);
            }

            /****OBJECTIVE****/
            p.setObj(p.newCtr("OBJ", new XPRBrelation(z)));  /* Define and set objective function */

            /****BOUNDS****/
            for(j=0;j<NJ;j++) start[j].setUB(NT-DUR[j]+1);
            /* Upper bounds on start time variables */

            /****SETS****/
            for(j=0;j<NJ;j++)
            {
                le = new XPRBexpr(0);
                for(t=0;t<(NT-DUR[j]+1);t++)  le += (t+1)*delta[j,t];
                set[j] = p.newSos("sosj",BCLconstant.XPRB_S1,le);
                }

            /****OUTPUT****/
            p.print();                     /* Print out the problem definition */
            p.exportProb(BCLconstant.XPRB_MPS,"expl1");  /* Output matrix to MPS file */
        }

    }

}
Back to examples browserPrevious exampleNext example