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





xbexpl1i.cs

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

  file xbexpl1i.cs
  ````````````````
  BCL user guide example.
  Version using index sets.

  (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 TestUGExpl1i
    {
        const int MAXNJ = 4;             /* Max. number of jobs */
        const int NT  = 10;             /* Time limit */

        //Define XPRBDATAPATH to wherever you have placed the data folder; here we expect it to be same directory as compiled example.
        static string XPRBDATAPATH = Directory.GetParent(System.Reflection.Assembly.GetExecutingAssembly().Location).FullName + "/Data";
        static string DATAFILE = XPRBDATAPATH + "/jobs/durations.dat";

        /**** DATA ****/
        int NJ = 0;	            /* Number of jobs read in */
        double[] DUR = new double[MAXNJ];          /* Durations of jobs   */

        XPRBindexSet Jobs;	    /* Job names */
        XPRBvar[] start;             /* Start times of jobs  */
        XPRBvar[,] delta;            /* Binaries for start times */
        XPRBvar z;                  /* Maximum completion time (makespan) */

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

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

        void readData()
        {
            string name;
            FileStream file;
            StreamReader fileStreamIn;

             /* Create a new index set */
            Jobs = p.newIndexSet("jobs", MAXNJ);


            file = new FileStream(DATAFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);

            object[] tempobj = new object[2];
            while((NJ<MAXNJ) && (p.XPRBreadarrline(fileStreamIn, 99, "{t} , {g} ", out tempobj, 1) == 2))
            {
                int dummy;
                name = (string)tempobj[0];
                DUR[NJ] = (double)tempobj[1];
                dummy = Jobs + name;
                NJ++;
            }

            fileStreamIn.Close();
            file.Close();

            System.Console.WriteLine("Number of jobs read: " + Jobs.getSize());
        }

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

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

            /****VARIABLES****/
                /* Create start time variables (incl. bounds) */
            start = new XPRBvar[NJ];
            if(start==null)
            {
                System.Console.WriteLine("Not enough memory for 'start' variables.");
                return;
            }
            for (j = 0; j < NJ; j++) start[j] = p.newVar("start", BCLconstant.XPRB_PL, 0, NT - DUR[j] + 1);
            z = p.newVar("z",BCLconstant.XPRB_PL,0,NT);  /* Declare the makespan variable */

            delta = new XPRBvar[NJ, NT];
            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" + Jobs.getIndexName(j) + "_" + (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(z));                   /* Define and set objective function */

            jobsSolve();                   /* Solve the problem */

        }

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

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

            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();
           TestUGExpl1i TestInstance = new TestUGExpl1i();

            TestInstance.readData();                     /* Read in the data */
            TestInstance.jobsModel();                    /* Define and solve the problem */

            return;
        }

    }

}
Back to examples browserPrevious exampleNext example