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





xbexpl1i.cxx

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

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

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

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

using namespace std;
using namespace ::dashoptimization;

#define MAXNJ 4             /* Max. number of jobs */   
#define NT   10             /* Time limit */   

#define DATAFILE XPRBDATAPATH "/jobs/durations.dat"

/**** DATA ****/
int NJ = 0;	            /* Number of jobs read in */
double DUR[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) */ 
 
void readData(XPRBprob &);  /* Read data from file  */
void jobsModel(XPRBprob &); /* Basic model formulation */
void jobsSolve(XPRBprob &); /* Solving and solution printing */
             
/*************************************************************************/

void readData(XPRBprob &p)
{ 
 char name[100];
 FILE *datafile;
                             /* Create a new index set */
 Jobs = p.newIndexSet("jobs", MAXNJ);

 datafile=fopen(DATAFILE,"r");  /* Open the data file for read access */
 while(NJ<MAXNJ && XPRBreadlinecb(XPRB_FGETS, datafile, 99, "T,d", 
                                  name, &DUR[NJ]))
 {                           /* Read in all (non-empty) lines up to the end 
                                 of the file */
  Jobs += name;              /* Add job to the index set */
  NJ++;
 }
 fclose(datafile);           /* Close the input file */
 cout << "Number of jobs read: " << Jobs.getSize() << endl;
}

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

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

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

 delta = new XPRBvar*[NJ];
 if(delta==NULL)
 { cout << "Not enough memory for 'delta' variables." << endl; exit(0); }
 for(j=0;j<NJ;j++)              /* Declare binaries for each job  */
 {
  delta[j] = new XPRBvar[NT];
  if(delta[j]==NULL)
  { cout << "Not enough memory for 'delta_j' variables." << endl; exit(0); }
  for(t=0;t<(NT-DUR[j]+1);t++)
   delta[j][t] = p.newVar(XPRBnewname("delta%s_%d",Jobs[j],t+1),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=0;
  for(t=0;t<(NT-DUR[j]+1);t++)  le += (t+1)*delta[j][t]; 
  p.newCtr(XPRBnewname("Link_%d",j+1), le == start[j]);
 } 
               
 for(j=0;j<NJ;j++)              /* One unique start time for each job  */
 { 
  le=0;
  for(t=0;t<(NT-DUR[j]+1);t++)  le += delta[j][t]; 
  p.newCtr(XPRBnewname("One_%d",j+1), le == 1);
 }      
              
/****OBJECTIVE****/
 p.setObj(z);                   /* Define and set objective function */ 

 jobsSolve(p);                  /* Solve the problem */

 delete [] start;
 for(j=0;j<NJ;j++) delete [] delta[j];
 delete [] delta;
} 

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

 for(j=0;j<NJ;j++)    
  for(t=0;t<NT-DUR[j]+1;t++)
   delta[j][t].setDir(XPRB_PR,10*(t+1)); 
            /* Give highest priority to variables for earlier start times */

 p.setSense(XPRB_MINIM);
 p.mipOptimize("");              /* Solve the problem as MIP */
 statmip = p.getMIPStat();       /* Get the MIP problem status */    
              
 if((statmip == XPRB_MIP_SOLUTION) || (statmip == XPRB_MIP_OPTIMAL))
                                 /* An integer solution has been found */
 {  
  cout << "Objective: " << p.getObjVal() << endl; 
  for(j=0;j<NJ;j++) 
  {                              /* Print the solution for all start times */
   cout << start[j].getName() << ": " << start[j].getSol() << endl; 
   for(t=0;t<NT-DUR[j]+1;t++) 
    cout <<  delta[j][t].getName() << ": " << delta[j][t].getSol() << " ";
   cout << endl;
  }
 } 
}

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

int main(int argc, char **argv) 
{
 XPRBprob p("Jobs");         /* Initialize BCL and a new problem */ 
 readData(p);                /* Read in the data */
 jobsModel(p);               /* Define and solve the problem */
 return 0;     
}


Back to examples browserPrevious exampleNext example