Initializing help system before first use

UG - Examples from 'BCL Reference Manual'


Type: Programming
Rating: 3 (intermediate)
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)
File(s): xbexpl1.cs, xbexpl1i.cs, xbexpl3.cs, xbexpl2.cs, xbcutex.cs, xbqpr12.cs, xbairport.cs, xbcontr1.cs, xbcontr2.cs, xbcontr2s.cs
Data file(s): durations.dat


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

    }

}

xbexpl1i.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

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

  (c) 2008 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 whatever folder you wish.
        const string XPRBDATAPATH = "../../data";
        const 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;     
        }

    }

}

xbexpl3.cs
/*************************************************************************
  BCL Example Problems
  ====================

  file xbexpl3.cs
  ```````````````
  User error handling.
/* This small, infeasible example shows how the error handling and all 
   printed messages can be intercepted by the user's program. This is done 
   by defining the corresponding BCL callback functions and changing 
   the error handling flag.
 
  (c) 2008 Fair Isaac Corporation
      Authors: S.Heipcke and D.Brett
*************************************************************************/


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


namespace Examples
{

    public class TestUGExpl3
    {
        public static int rtsbefore = 1;
        
        public void modexpl3(ref XPRBprob prob)
        {
            XPRBvar[] x = new XPRBvar[3];
            XPRBctr[] ctr = new XPRBctr[2];
            XPRBexpr cobj;
            int i;

            for(i=0;i<2;i++) 
                x[i] = prob.newVar("x_"+i, BCLconstant.XPRB_UI, 0, 100);

            /* Create the constraints:
            C1: 2x0 + 3x1 >= 41
            C2:  x0 + 2x1  = 13 */
            XPRBexpr C1linexp = new XPRBexpr();

            XPRBexpr C2linexp = new XPRBexpr();
            C1linexp = 2 * x[0] + 3 * x[1];
            C2linexp = x[0] + 2 * x[1];
            prob.newCtr("C1", C1linexp >= 41);
            prob.newCtr("C2", C2linexp == 13); 


            /* Uncomment the following line to cause an error in the model that
            triggers the user error handling: */

            //x[3] = prob.newVar("x_2", BCLconstant.XPRB_UI, 10, 1);

            /* Objective: minimize x0+x1 */
            cobj = new XPRBexpr(0);
            for(i=0;i<2;i++) 
                cobj += x[i];
            prob.setObj(prob.newCtr("OBJ", cobj));

            /* Set objective sense to minimization */
            prob.setSense(BCLconstant.XPRB_MINIM);

            /* Print current problem definition */
            prob.print();

            /* Solve the LP */
            prob.lpOptimize();
            prob.printF("Problem status: " + prob.getProbStat() + 
                "  LP status: " + prob.getLPStat() + "  MIP status: " + 
                prob.getMIPStat() + "\n");

            /* This problem is infeasible, that means the following command 
             * will fail.
             * It prints a warning if the message level is at least 2 */

            prob.printF("Objective: " + prob.getObjVal() + "\n");

            /* Print solution values */ 
            for(i=0;i<2;i++)
                prob.printF(x[i].getName() + ":" + x[i].getSol() + ", ");
            prob.printF("\n");
        }

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

        /**** User error handling function ****/
        public static void usererror(IntPtr prob, object vp, int num, int type, 
                                                                string t)
        {
            Exception eBCL = new Exception("Error in usererror().");
            System.Console.WriteLine("BCL error " +num+ ": " + t);
            if(type==BCLconstant.XPRB_ERR) 
                throw eBCL; 
        }

        /**** User printing function ****/
        public static void userprint(IntPtr prob, object vp, string msg)   
        {

            /* Print 'BCL output' whenever a new output line starts,
            otherwise continue to print the current line. */ 
            if(rtsbefore==1)
                System.Console.Write("BCL output: " + msg);
            else
                System.Console.Write(msg);

            rtsbefore = (msg.Length>0 && msg[msg.Length-1]=='\n') ? 1 : 0;
        }

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

        // This is where one might add custom logging
        static void DoSomeErrorLogging(string msg)
        {
            Console.WriteLine("Here's an error message! {0}", msg);
        }

        public static int Main()
        {
            try
            {
                /* Switch to error handling by the user's program */
                XPRB.setErrCtrl(0); // no auto quit on error
                int initCode = XPRB.init();
                if (initCode != 0 && initCode != 32) // both values are valid
                {
                    DoSomeErrorLogging(Optimizer.XPRS.GetLicErrMsg());
                    return initCode;
                }
                TestUGExpl3 TestInstance = new TestUGExpl3();
                
                XPRBprob prob = new XPRBprob("EXPL3");
                if (!prob.isValid())
                {
                    DoSomeErrorLogging("Unable to create XPRBprob \"EXPL3\"");
                    return 1;
                }

                /* Set the printing flag. Try other values:
                        0 - no printed output, 1 - only errors,
                        2 - errors and warnings, 3 - all messages */
                prob.setMsgLevel(2);

                /* Define the printing callback function */
                prob.MessageCallbacks += new XPRBMessageCallback(userprint);
                

                try
                {
                    prob.ErrorCallbacks += new XPRBErrorCallback(usererror);
                    
                    /* Formulate and solve the problem */                    
                    TestInstance.modexpl3(ref prob);

                    System.Console.WriteLine("I'm about to exit cleanly");
                    return 0;
                }
                catch
                {
                    System.Console.WriteLine("I cannot build the problem");
                    return 1;
                }

            }
            catch
            {
                System.Console.WriteLine("I cannot create the problem");
                return 1;
            }
        } 
    }
}

xbexpl2.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbexpl2.cs
  ```````````````
  Transportation model from the Release 10.5 Supplement.

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

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


namespace Examples
{

    public class TestUGExpl2
    {

        const int MaxSuppliers = 100;         /* Max. number of suppliers */
        const int MaxCustomers = 1000;        /* Max. number of customers */
        const int MaxArcs = 10000;            /* Max. number of non-zero cost values */
        
        //Define XPRBDATAPATH to whichever folder you wish.
        const string XPRBDATAPATH = "../../data";

        const string DEMANDFILE = XPRBDATAPATH + "/trans/ex2dem1.dat";
        /* Demand data file (comma-separated format) */
        const string  AVAILFILE = XPRBDATAPATH + "/trans/ex2avail.dat";
        /* Supply data file (comma-separated format) */
        const string  COSTFILE = XPRBDATAPATH + "/trans/ex2cost.dat";  
        /* Cost data file (comma-separated format) */

        XPRBindexSet Suppliers;          /* Set of suppliers */
        XPRBindexSet Customers;          /* Set of customers */
        double[] AVAIL = new double[MaxSuppliers];      /* Availability of products */
        double[] DEMAND = new double[MaxCustomers];     /* Demand by customers */

        public struct CostStruct{
            public int suppl;
            public int custm;
            public double value;
        } ;                 /* Cost per supplier-customer pair */

        CostStruct[] COST = new CostStruct[MaxArcs];
        
        int NSuppl=0,NCustom=0, NArc=0;  /* Actual numbers of suppliers, customers, 
        and arcs */

        XPRBprob p = new XPRBprob("Trans");             /* Initialize a new problem in BCL */

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

        void modTrans()
        {
            XPRBexpr lobj;
            XPRBexpr[] av;
            XPRBexpr[] de;
            int s,c,a;
            XPRBvar[] x;

            /****VARIABLES****/
            x = new XPRBvar[NArc];
            if(x==null) System.Console.WriteLine("Allocating memory for variables failed.");
            for(a=0; a<NArc; a++) x[a]=p.newVar("x");

            /****OBJECTIVE****/
            lobj = new XPRBexpr();
            for(a=0; a<NArc; a++)
                lobj += COST[a].value*x[a];
            p.setObj(p.newCtr("OBJ", lobj));  /* Define & set objective function */ 

            /****CONSTRAINTS****/
            /**** Create all constraints in a single loop ****/
            /* Initialize the linear expressions */
            av = new XPRBexpr[NSuppl];
            if(av==null) System.Console.WriteLine("Not enough memory for AV constraints.");
            de = new XPRBexpr[NCustom];
            if(de==null) System.Console.WriteLine("Not enough memory for DE constraints.");

            //Initialise all the XPRBexprs:
            for (int i = 0; i < NSuppl; i++)
                av[i] = new XPRBexpr();
            for (int i = 0; i < NCustom; i++)
                de[i] = new XPRBexpr();

            for(a=0; a<NArc; a++)             /* Add terms to expressions one-by-one */
            {
                av[COST[a].suppl] += x[a];
                de[COST[a].custm] += x[a];
            }                                 
            /* Terminate the constraint definition */
            for(s=0; s<NSuppl; s++)  p.newCtr("Avail", av[s] <= AVAIL[s]);
            for(c=0; c<NCustom; c++)  p.newCtr("Demand", de[c] >= DEMAND[c]);

            /****SOLVING + OUTPUT****/
            p.exportProb(BCLconstant.XPRB_MPS,"trans");   /* Matrix generation & output to MPS file */

            p.setSense(BCLconstant.XPRB_MINIM);
            p.lpOptimize();
            System.Console.WriteLine("Objective: " + p.getObjVal());   /* Get objective value */

            for(a=0; a<NArc; a++)             /* Print out the solution values */
                if(x[a].getSol()>0)
                {
                    System.Console.Write(Suppliers.getIndexName(COST[a].suppl) + " (" + AVAIL[COST[a].suppl] + ") -> ");
                    System.Console.Write(Customers.getIndexName(COST[a].custm) + " (" + DEMAND[COST[a].custm] + "): ");
                    System.Console.WriteLine(x[a].getSol());  
                }
        }

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

        /**** Read data from files ****/
        public void readData()
        {
            double value;
            FileStream file;
            StreamReader fileStreamIn;
            string name, name2;

            /* Create supplier and customer index sets */
            Suppliers=p.newIndexSet("suppl",MaxSuppliers);
            Customers=p.newIndexSet("custom",MaxCustomers);

            /* Read the demand data file */
            file = new FileStream(DEMANDFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);
            object[] tempobj = new object[3];
            while (p.XPRBreadarrline(fileStreamIn, 200, "{T} , {g} ", out tempobj, 1) == 2)
            {
                name = (string)tempobj[0];
                value = (double)tempobj[1];
                DEMAND[(Customers + name)] = value;
            }
            fileStreamIn.Close();
            file.Close();
            NCustom = Customers.getSize();


            /* Read the supply data file */
            file = new FileStream(AVAILFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);
            while (p.XPRBreadarrline(fileStreamIn, 200, "{T} , {g} ", out tempobj, 1) == 2)
            {
                name = (string)tempobj[0];
                value = (double)tempobj[1];
                AVAIL[Suppliers + name] = value;
            }
            fileStreamIn.Close();
            file.Close();
            NSuppl = Suppliers.getSize();

            /* Read the cost data file */
            NArc = 0;
            file = new FileStream(COSTFILE, FileMode.Open, FileAccess.Read);
            fileStreamIn = new StreamReader(file);
            while (p.XPRBreadarrline(fileStreamIn, 200, "{T} , {T} , {g} ", out tempobj, 1) == 3)
            {
                name = (string)tempobj[0];
                name2 = (string)tempobj[1];
                value = (double)tempobj[2];

                COST[NArc].suppl = Suppliers.getIndex(name);
                COST[NArc].custm = Customers.getIndex(name2);

                if (COST[NArc].custm < 0) 
                    System.Console.WriteLine("Cust(" + name2 + ")");
                if (COST[NArc].suppl < 0)
                    System.Console.WriteLine("Supp(" + name + ")");

                COST[NArc++].value = value;
            }
            fileStreamIn.Close();
            file.Close();

            System.Console.WriteLine("C: " + NCustom + "  S: " + NSuppl + "  A: " + NArc);
        }

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

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

            TestInstance.readData();            /* Data input from file */
            TestInstance.modTrans();            /* Formulate and solve the problem */

            return;
        } 
    }
}

xbcutex.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbcutex.cs
  ```````````````
  Simplified version of xbexpl1.cxx showing how 
  to define cuts with BCL.

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

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


namespace Examples
{

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

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

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

        /***********************************************************************/
        //public delegate int CallbackDelegate(IntPtr oprob, XPRBprobStruct vd);

        //public int usrcme(IntPtr oprob, XPRBprobStruct vd)
        public int usrcme(XPRSprob xprsp, object vd)
        {
            XPRBcut[] ca = new XPRBcut[2];
            int num;
            int i=0;
            XPRBprob bprob = (XPRBprob)vd;
            bprob.beginCB(xprsp);
    
            /* In terms of an example, we add a few additional constraints (without
            any relation to the original problem) at the second node of the MIP
            search tree. These constraints/cuts are applied at this node and all 
            its child nodes. */

            num = xprsp.Nodes;
            if(num == 2) 
            {
                ca[0] = bprob.newCut(start[1]+2 <= start[0], 2); 
                ca[1] = bprob.newCut((4*start[2]) - (5.3*start[3]) <= -17, 2);
                System.Console.WriteLine("Adding constraints:");
                for(i=0;i<2;i++) ca[i].print();
                if(bprob.addCuts(ca,2) != 0) System.Console.WriteLine("Problem with adding cuts.");
            }

            bprob.endCB();            
            return 0;                      /* Call this function once per node */
        }

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

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

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

        public void jobsSolve()             
        { 
            int j,t,statmip; 
            CutmgrCallback del = new CutmgrCallback(usrcme);
            XPRSprob xprsp = p.getXPRSprob();

            xprsp.HeurStrategy = 0;
            xprsp.CutStrategy = 0;

            /* Switch heuristics and cut generation off:
            otherwise this problem is solved in the
            first node of the MIP search tree */
            
            p.setCutMode(1);                /* Enable the cut mode */

            xprsp.AddCutmgrCallback(del, (object)p);

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

            TestInstance.jobsModel();                   /* Basic problem definition */
            TestInstance.jobsSolve();                   /* Solve and print solution */

            return;     
        }
    }
}

xbqpr12.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbqpr12.cs
  ```````````````
  Small Quadratic Programming example from
  Release 12 Supplement.
       minimize x1 + x1^2 +2x1x2 +2x2^2 +x4^2
       s.t. C1:  x1 +2x2 -4x4 >= 0
            C2: 3x1 -2x3 - x4 <= 100
            C3: 10 <= x1 +3x2 +3x3 -2x4 <= 30
            0<=x1<=20
            0<=x2,x3
            x4 free

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

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


namespace Examples
{

    public class TestUGQpr12
    {

        const int NXPRBvar = 4;

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

        public static void Main()
        {
            XPRB.init();
            XPRBctr c;
            XPRBexpr qobj;
            XPRBvar[] x = new XPRBvar[NXPRBvar];
            int i;
            XPRBprob p = new XPRBprob("QPr12");     	/* Initialize a new problem in BCL */

            /**** VARIABLES ****/
            x[0] = p.newVar("x1", BCLconstant.XPRB_PL, 0, 20);
            x[1] = p.newVar("x2");
            x[2] = p.newVar("x3");
            x[3] = p.newVar("x4", BCLconstant.XPRB_PL, -BCLconstant.XPRB_INFINITY, BCLconstant.XPRB_INFINITY);

            /****OBJECTIVE****/
            /* Define the objective function */
            qobj = new XPRBexpr(x[0]) + x[0].sqr()  + 2*(x[0]*x[1])  + 2*x[1].sqr()  + x[3].sqr();
            p.setObj(qobj);

            /**** CONSTRAINTS ****/
            p.newCtr("C1", x[0] + 2*x[1] - 4*x[3] >= 0);
            p.newCtr("C2", 3*x[0] - 2*x[2] -x[3] <= 100);
            c = p.newCtr("C3", x[0] + 3*x[1] + 3*x[2] - 2*x[3] );
            c.setRange(10,30);

            /****SOLVING + OUTPUT****/
            p.print();			  /* Print out the problem definition */
            p.exportProb(BCLconstant.XPRB_MPS, "QPr12");  /* Output the matrix in MPS format */
            p.exportProb(BCLconstant.XPRB_LP, "QPr12");   /* Output the matrix in LP format */

            p.setSense(BCLconstant.XPRB_MINIM);      	  /* Choose the sense of the optimization */   
            p.lpOptimize();          		  /* Solve the QP-problem */

            System.Console.WriteLine("Objective function value: " + p.getObjVal());
            for(i=0;i<NXPRBvar;i++)
                System.Console.Write(x[i].getName() + ": " + x[i].getSol() + ", ");
            System.Console.WriteLine();

            return;
        }

    }

}

xbairport.cs
/****************************************************************
  BCL Example Problems
  ====================

  file xbairport.cs
  `````````````````
  QCQP problem by
      Rodrigo de Barros Nabholz & Maria Aparecida Diniz Ehrhardt
      November 1994, DMA - IMECC- UNICAMP.
  Based on AMPL model airport.mod by Hande Y. Benson
  (Source: http://www.orfe.princeton.edu/~rvdb/ampl/nlmodels/ )
   
  (c) 2008 Fair Isaac Corporation
      authors: S.Heipcke, D.Brett, June 2008
****************************************************************/

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


namespace Examples
{

    public class TestBAirport
    {
        const int N = 42;	

        public static void Main()
        {
            XPRB.init();
            double[] cx = {-6.3, -7.8, -9, -7.2, -5.7, -1.9, -3.5, -0.5, 1.4, 4,
               2.1, 5.5, 5.7, 5.7, 3.8, 5.3, 4.7, 3.3, 0, -1, -0.4, 4.2, 
               3.2, 1.7, 3.3, 2, 0.7, 0.1, -0.1, -3.5, -4, -2.7, -0.5, -2.9,
               -1.2, -0.4, -0.1, -1, -1.7, -2.1, -1.8, 0};
            double[] cy = {8, 5.1, 2, 2.6, 5.5, 7.1, 5.9, 6.6, 6.1, 5.6, 4.9, 4.7, 
               4.3, 3.6, 4.1, 3, 2.4, 3, 4.7, 3.4, 2.3, 1.5, 0.5, -1.7, -2,
               -3.1, -3.5, -2.4, -1.3, 0, -1.7, -2.1, -0.4, -2.9, -3.4, -4.3,
               -5.2, -6.5, -7.5, -6.4, -5.1, 0};
            double[] r = {0.09, 0.3, 0.09, 0.45, 0.5, 0.04, 0.1, 0.02, 0.02, 0.07, 0.4, 
              0.045, 0.05, 0.056, 0.36, 0.08, 0.07, 0.36, 0.67, 0.38, 0.37, 
              0.05, 0.4, 0.66, 0.05, 0.07, 0.08, 0.3, 0.31, 0.49, 0.09, 
              0.46, 0.12, 0.07, 0.07, 0.09, 0.05, 0.13, 0.16, 0.46, 0.25, 0.1};
            int i, j;
            XPRBvar[] x = new XPRBvar[N];
            XPRBvar[] y = new XPRBvar[N];
            XPRBexpr qe;
            XPRBctr cobj, c;
            XPRBprob prob = new XPRBprob("airport");   /* Initialize a new problem in BCL */

            /**** VARIABLES ****/
            for(i=0;i<N;i++) 
                x[i] = prob.newVar("x("+(i+1)+")", BCLconstant.XPRB_PL, -10, 10);
            for(i=0;i<N;i++)
                y[i] = prob.newVar("y("+(i+1)+")", BCLconstant.XPRB_PL, -10, 10);

            /****OBJECTIVE****/
            /*  sum(i in 1..N-1,j in i+1..N) ((x(i)-x(j))^2+(y(i)-y(j))^2)  */
            qe=new XPRBexpr();
            for(i=0;i<N-1;i++)
                for(j=i+1;j<N;j++) qe+= (x[i]-x[j]).sqr() + (y[i]-y[j]).sqr();
            cobj = prob.newCtr("Obj", qe );
            prob.setObj(cobj);                     /* Set objective function */ 

            /**** CONSTRAINTS ****/
            /*  (x(i)-cx(i))^2+(y(i)-cy(i))^2-r(i) <= 0  */
            for(i=0;i<N;i++)
            c = prob.newCtr("Constr", (x[i]-cx[i]).sqr() + (y[i]-cy[i]).sqr() -r[i] <= 0);

            /****SOLVING + OUTPUT****/
                prob.setSense(BCLconstant.XPRB_MINIM);    /* Choose the sense of optimization */

            /****PROBLEM PRINTING + MATRIX OUTPUT****/
            /*
            prob.print();
            prob.exportProb(BCLconstant.XPRB_MPS, "airport");
            prob.exportProb(BCLconstant.XPRB_LP, "airport");
            */

            prob.lpOptimize();                       /* Solve the problem */

            System.Console.WriteLine("Solution: " + prob.getObjVal());
            for (i = 0; i < N; i++)
            {
                System.Console.Write(x[i].getName() + ": " + x[i].getSol() + ", ");
                System.Console.WriteLine(y[i].getName() + ": " + y[i].getSol());
            }

            return;
        }
    }
}

xbcontr1.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbcontr1.cs
  ````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  in Xpress-Optimizer.

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

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


namespace Examples
{

    public class TestUGContr1
    {
        const int District = 6;               /* Number of districts */
        const int Contract = 10;              /* Number of contracts */

        /**** DATA ****/
        int[] OUTPUT = {50, 40, 10, 20, 70, 50}; /* Max. output per district */
        int[] COST   = {50, 20, 25, 30, 45, 40}; /* Cost per district */
        int[] VOLUME   = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20};  
        /* Volume of contracts */

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

        public static void Main()
        {
            XPRB.init();
            int d,c;
            XPRBexpr l1,l2,lobj;
            
            /* Variables indicating whether a project is chosen */
            XPRBvar[,] x = new XPRBvar[District,Contract];  
            
            /* Quantities allocated to contractors */
            XPRBvar[,] y = new XPRBvar[District,Contract];  
            
            int i, ncol, len, stat;
            double[] sol;
            double val;
            
            /* Initialize a new problem in BCL */
            XPRBprob p = new XPRBprob("Contr1");                
            
            XPRSprob xprsp;
            TestUGContr1 TestInstance = new TestUGContr1();

            /**** VARIABLES ****/
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                {
                    x[d,c] = p.newVar("x_d" + (d+1) + "c" + (c+1), 
                    	      BCLconstant.XPRB_BV);
                    y[d,c] = p.newVar("q_d" + (d+1) + "c" + (c+1), 
                    	      BCLconstant.XPRB_SC, 0, TestInstance.OUTPUT[d]);
                    y[d,c].setLim(5);
                } 

            /****OBJECTIVE****/
            lobj = new XPRBexpr();
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                    lobj += TestInstance.COST[d]*y[d,c];   

            p.setObj(p.newCtr("OBJ",lobj));    /* Set the objective function */

            /**** CONSTRAINTS ****/
            for(c=0;c<Contract;c++)
            {
                l1 = new XPRBexpr();
                l2 = new XPRBexpr();  
                for(d=0;d<District;d++)
                {
                    l1 += y[d,c];
                    l2 += x[d,c];
                }
                
                /* "Size": cover the required volume */
                p.newCtr("Size", l1 >= TestInstance.VOLUME[c]);  
                
                /* "Min": at least 2 districts per contract */
                p.newCtr("Min", l2 >= 2 ); 	
            }

	    /* Do not exceed max. output of any district */
            for(d=0;d<District;d++)        
            {
                l1 = new XPRBexpr();
                for(c=0;c<Contract;c++)
                l1 += y[d,c];
                p.newCtr("Output", l1 <= TestInstance.OUTPUT[d]);
            } 

            /* If a contract is allocated to a district,
               then at least 1 unit is allocated to it */                                            
            for(d=0;d<District;d++) 
                for(c=0;c<Contract;c++)
                    p.newCtr("XY", x[d,c] <= y[d,c]);

            /****SOLVING + OUTPUT****/
            p.loadMat();                   /* Load the matrix explicitly */
            xprsp = p.getXPRSprob();
            xprsp.ChgObjSense(ObjSense.Minimize);
            xprsp.MipOptimize();              /* Solve the MIP problem */

            stat = (int)xprsp.MIPStatus;
            /* Get the global (MIP) status */

	    /* Test whether an integer solution was found */
            if (((int)MIPStatus.Solution==stat) || 
            	((int)MIPStatus.Optimal==stat))
            {                              
                val = xprsp.MIPObjVal;
                System.Console.WriteLine("Objective: " + val);
                
                ncol = xprsp.Cols;
                sol = new double[ncol];
                
                xprsp.GetMipSol(sol);
                /* Get the primal solution values */
                len = xprsp.NameLength;
                /* Get the maximum name length */


                string[] names = xprsp.GetNames(2, 0, ncol - 1);
                // Get the variable names
                for (i = 0; i < ncol; i++)         // Print out the solution
                    if (sol[i] != 0)
                    {
                        System.Console.Write(names[i] + ": " + sol[i] + ", ");
                    }
                System.Console.WriteLine();

            }

            return;
        } 

    }

}

xbcontr2.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbcontr2.cs
  ````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  and callbacks in Xpress-Optimizer.

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

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


namespace Examples
{

    public class TestUGContr2
    {
        const int District = 6;                  /* Number of districts */
        const int Contract = 10;                 /* Number of contracts */

        /**** DATA ****/
        int[] OUTPUT = {50, 40, 10, 20, 70, 50}; /* Max. output per district */
        int[] COST   = {50, 20, 25, 30, 45, 40}; /* Cost per district */
        int[] VOLUME = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20};  
        /* Volume of contracts */


        /*********************************************************************/
        public void printsolution(XPRSprob xprsp, object vp)
        {
            int num, d, c;
            XPRBprob bprob;
            XPRBvar y;

            bprob = (XPRBprob)vp;
            bprob.beginCB(xprsp);
            num = xprsp.MIPSols;
            bprob.sync(BCLconstant.XPRB_XPRS_SOL);                  /* Update BCL solution values */
            System.Console.WriteLine("Solution " + num + ": Objective value: " + bprob.getObjVal()); 

            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                {
                    y = bprob.getVarByName("q_d" + (d+1) + "c" + (c+1));
                    if( (y.getColNum()>-1) && (y.getSol() != 0))
                        System.Console.WriteLine(y.getName() + ": " + y.getSol()); 
                }
            bprob.endCB();

            return;
        }

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

        public static void Main()
        {
           XPRB.init();
           int d,c;
            XPRBexpr l1,l2,lobj;
            XPRBvar[,] x = new XPRBvar[District,Contract];  /* Variables indicating whether a project 
            is chosen */
            XPRBvar[,] y = new XPRBvar[District,Contract];  /* Quantities allocated to contractors */
            XPRBprob p = new XPRBprob("Contr2");           /* Initialize a new problem in BCL */
            TestUGContr2 TestInstance = new TestUGContr2();
            IntsolCallback del = new IntsolCallback(TestInstance.printsolution);
            XPRSprob xprsp;

            /**** VARIABLES ****/
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                {
                    x[d, c] = p.newVar("x_d" + (d+1) + "c" + (c+1), BCLconstant.XPRB_BV);
                    y[d, c] = p.newVar("q_d" + (d+1) + "c" + (c+1), BCLconstant.XPRB_SC, 0, TestInstance.OUTPUT[d]);
                    y[d,c].setLim(5);
                } 

            /****OBJECTIVE****/
            lobj = new XPRBexpr();
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                    lobj += TestInstance.COST[d] * y[d, c];   

            p.setObj(p.newCtr("OBJ",lobj));       /* Set the objective function */

            /**** CONSTRAINTS ****/
            for(c=0;c<Contract;c++)
            {
                l1= new XPRBexpr(0);
                l2= new XPRBexpr(0);  
                for(d=0;d<District;d++)
                {
                    l1 += y[d,c];
                    l2 += x[d,c];
                }
                p.newCtr("Size", l1 >= TestInstance.VOLUME[c]);   /* "Size": cover the required volume */
                p.newCtr("Min", l2 >= 2 ); 	/* "Min": at least 2 districts per contract */
            }

            for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
            {
                l1= new XPRBexpr(0);
                for(c=0;c<Contract;c++)
                    l1 += y[d,c];
                p.newCtr("Output", l1 <= TestInstance.OUTPUT[d]);
            } 

            for(d=0;d<District;d++)        /* If a contract is allocated to a district,
                                           then at least 1 unit is allocated to it */
                for(c=0;c<Contract;c++)
                    p.newCtr("XY", x[d,c] <= y[d,c]);

            /****SOLVING + OUTPUT****/
            xprsp = p.getXPRSprob();
            xprsp.AddIntsolCallback(del, (object)p);
            /* Define an integer solution callback */

            p.setSense(BCLconstant.XPRB_MINIM);
            p.mipOptimize();

            return;
        } 

    }

}

xbcontr2s.cs
/********************************************************
  Xpress-BCL C# Example Problems
  ==============================

  file xbcontr2.cs
  ````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  and callbacks in Xpress-Optimizer.
  --- MIP Single-threaded ---

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

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


namespace Examples
{

    public class TestUGContr2s
    {
        const int District = 6;                  /* Number of districts */
        const int Contract = 10;                 /* Number of contracts */

        /**** DATA ****/
        int[] OUTPUT = {50, 40, 10, 20, 70, 50}; /* Max. output per district */
        int[] COST   = {50, 20, 25, 30, 45, 40}; /* Cost per district */
        int[] VOLUME = {20, 10, 30, 15, 20, 30, 10, 50, 10, 20};  
        /* Volume of contracts */


        /*********************************************************************/
        public void printsolution(XPRSprob xprsp, object vp)
        {
            int num, d, c;
            XPRBprob bprob;
            XPRBvar y;

            bprob = (XPRBprob)vp;
            bprob.beginCB(xprsp);
            num = xprsp.MIPSols;
            bprob.sync(BCLconstant.XPRB_XPRS_SOL);                  /* Update BCL solution values */
            System.Console.WriteLine("Solution " + num + ": Objective value: " + bprob.getObjVal()); 

            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                {
                    y = bprob.getVarByName("q_d" + (d+1) + "c" + (c+1));
                    if( (y.getColNum()>-1) && (y.getSol() != 0))
                        System.Console.WriteLine(y.getName() + ": " + y.getSol()); 
                }
            bprob.endCB();

            return;
        }

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

        public static void Main()
        {
           XPRB.init();
           int d,c;
            XPRBexpr l1,l2,lobj;
            XPRBvar[,] x = new XPRBvar[District,Contract];  /* Variables indicating whether a project 
            is chosen */
            XPRBvar[,] y = new XPRBvar[District,Contract];  /* Quantities allocated to contractors */
            XPRBprob p = new XPRBprob("Contr2");           /* Initialize a new problem in BCL */
            TestUGContr2s TestInstance = new TestUGContr2s();
            IntsolCallback del = new IntsolCallback(TestInstance.printsolution);
            XPRSprob xprsp;

            /**** VARIABLES ****/
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                {
                    x[d, c] = p.newVar("x_d" + (d+1) + "c" + (c+1), BCLconstant.XPRB_BV);
                    y[d, c] = p.newVar("q_d" + (d+1) + "c" + (c+1), BCLconstant.XPRB_SC, 0, TestInstance.OUTPUT[d]);
                    y[d,c].setLim(5);
                } 

            /****OBJECTIVE****/
            lobj = new XPRBexpr();
            for(d=0;d<District;d++)
                for(c=0;c<Contract;c++)
                    lobj += TestInstance.COST[d] * y[d, c];   

            p.setObj(p.newCtr("OBJ",lobj));       /* Set the objective function */

            /**** CONSTRAINTS ****/
            for(c=0;c<Contract;c++)
            {
                l1= new XPRBexpr(0);
                l2= new XPRBexpr(0);  
                for(d=0;d<District;d++)
                {
                    l1 += y[d,c];
                    l2 += x[d,c];
                }
                p.newCtr("Size", l1 >= TestInstance.VOLUME[c]);   /* "Size": cover the required volume */
                p.newCtr("Min", l2 >= 2 ); 	/* "Min": at least 2 districts per contract */
            }

            for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
            {
                l1= new XPRBexpr(0);
                for(c=0;c<Contract;c++)
                    l1 += y[d,c];
                p.newCtr("Output", l1 <= TestInstance.OUTPUT[d]);
            } 

            for(d=0;d<District;d++)        /* If a contract is allocated to a district,
                                           then at least 1 unit is allocated to it */
                for(c=0;c<Contract;c++)
                    p.newCtr("XY", x[d,c] <= y[d,c]);

            /****SOLVING + OUTPUT****/
            xprsp = p.getXPRSprob();
            /* Desactivate parallel MIP (for synchronization of BCL and Optimizer) */
            xprsp.MIPThreads = 1;
            xprsp.AddIntsolCallback(del, (object)p);
            /* Define an integer solution callback */

            p.setSense(BCLconstant.XPRB_MINIM);
            p.mipOptimize();

            return;
        } 

    }

}