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)
  • 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.cxx

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

  file xbexpl2.cxx
  ````````````````
  Transportation model demonstrating use of index sets.

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


#include <iostream>
#include <cstdio>
#include "xprb_cpp.h"

using namespace std;
using namespace ::dashoptimization;

#define MaxSuppliers 100         /* Max. number of suppliers */
#define MaxCustomers 1000        /* Max. number of customers */
#define MaxArcs 10000            /* Max. number of non-zero cost values */
#define DEMANDFILE XPRBDATAPATH "/trans/ex2dem1.dat"  
                                 /* Demand data file (comma-separated format) */
#define AVAILFILE XPRBDATAPATH "/trans/ex2avail.dat" 
                                 /* Supply data file (comma-separated format) */
#define COSTFILE XPRBDATAPATH "/trans/ex2cost.dat"   
                                 /* Cost data file (comma-separated format) */

XPRBindexSet Suppliers;          /* Set of suppliers */
XPRBindexSet Customers;          /* Set of customers */
double AVAIL[MaxSuppliers];      /* Availability of products */
double DEMAND[MaxCustomers];     /* Demand by customers */
struct {
        int suppl;
        int custm;
        double value;
} COST[MaxArcs];                 /* Cost per supplier-customer pair */

int NSuppl=0,NCustom=0, NArc=0;  /* Actual numbers of suppliers, customers, 
                                    and arcs */

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

void modTrans(XPRBprob &p)
{
 XPRBexpr lobj, *av,*de;
 int s,c,a;
 XPRBvar *x;
 
/****VARIABLES****/
 x = new XPRBvar[NArc];
 if(x==NULL) cout << "Allocating memory for variables failed." << endl;
 for(a=0; a<NArc; a++) x[a]=p.newVar("x");
     
/****OBJECTIVE****/ 
 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) cout << "Not enough memory for AV constraints." << endl;
 de = new XPRBexpr[NCustom];
 if(de==NULL) cout << "Not enough memory for DE constraints." << endl;

 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(XPRB_MPS,"trans");   /* Matrix generation & output to MPS file */

 p.lpOptimize("");                 /* Solve the LP-problem */
 cout << "Objective: " << p.getObjVal() << endl;   /* Get objective value */

 for(a=0; a<NArc; a++)             /* Print out the solution values */
 if(x[a].getSol()>0)
 {
  cout << Suppliers[COST[a].suppl] << " (" << AVAIL[COST[a].suppl] << ") -> ";
  cout << Customers[COST[a].custm] << " (" << DEMAND[COST[a].custm] << "): ";
  cout << x[a].getSol() << endl;  
 }
 delete [] de;   
 delete [] av;
 delete [] x;
}

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

    /**** Read data from files ****/
void readData(XPRBprob &p)
{
 double value;
 FILE *datafile;
 char name[100], name2[100];
 
        /* Create supplier and customer index sets */
 Suppliers=p.newIndexSet("suppl",MaxSuppliers);
 Customers=p.newIndexSet("custom",MaxCustomers);
 
        /* Read the demand data file */
 datafile=fopen(DEMANDFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name, &value) == 2)
  DEMAND[Customers+=name]=value;
 fclose(datafile);
 NCustom = Customers.getSize();

        /* Read the supply data file */
 datafile=fopen(AVAILFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name, &value) == 2)
  AVAIL[Suppliers+=name]=value;
 fclose(datafile);
 NSuppl = Suppliers.getSize();

        /* Read the cost data file */
 NArc = 0;
 datafile=fopen(COSTFILE,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,T,g", name, 
        name2, &value) == 3)
 {
  COST[NArc].suppl = Suppliers[name];
  COST[NArc].custm = Customers[name2];
  if(COST[NArc].custm<0) printf("Cust(%s)\n",name2);
  if(COST[NArc].suppl<0) printf("Supp(%s)\n",name);
  COST[NArc++].value = value;
 }
 fclose(datafile);
 printf("C: %d  S: %d  A: %d\n",NCustom,NSuppl,NArc);
}

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

int main(int argc, char **argv)
{
 XPRBprob p("Trans");   /* Initialize a new problem in BCL */
 readData(p);           /* Data input from file */
 modTrans(p);           /* Formulate and solve the problem */
 
 return 0;
} 

Back to examples browserPrevious exampleNext example