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





xbexpl2.cs

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

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

  (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 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 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 DEMANDFILE = XPRBDATAPATH + "/trans/ex2dem1.dat";
        /* Demand data file (comma-separated format) */
        static string  AVAILFILE = XPRBDATAPATH + "/trans/ex2avail.dat";
        /* Supply data file (comma-separated format) */
        static 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;
        }
    }
}
Back to examples browserPrevious exampleNext example