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





xbexpl1.cxx

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

  file xbexpl1.cxx
  ````````````````
  BCL user guide example.
  Definition of variables and constraints, 
  variable arrays and SOS, followed by file output,
  solving and printing of solutions.

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

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

using namespace std;
using namespace ::dashoptimization;

/**************************************************************************/
/* Define the following option to try out a problem formulation using     */
/* Special Ordered Sets:                                                  */
#undef SOS

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

#define NJ    4             /* Number of jobs */   
#define NT   10             /* Time limit */   

/**** DATA ****/
double DUR[] = {3,4,2,2};   /* Durations of jobs   */ 

XPRBvar start[NJ];          /* Start times of jobs  */ 
XPRBvar delta[NJ][NT];      /* Binaries for start times */  
XPRBvar z;                  /* Maximum completion time (makespan) */ 
XPRBsos set[NJ];            /* Sets regrouping start times for jobs */
 
void jobsModel(XPRBprob &); /* Basic model formulation */
void jobsModelb(XPRBprob &);/* Model using SOS */
void jobsSolve(XPRBprob &); /* Solving and solution printing */
             
/*************************************************************************/

void jobsModel(XPRBprob &p)
{
 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",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(XPRBnewname("delta%d%d",j+1,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(p.newCtr("OBJ", 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(XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 

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

#ifndef SOS
 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 */
#else
 for(j=0;j<NJ;j++)    
  set[j].setDir(XPRB_DN);        /* First branch downwards on sets */
#endif

 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 */ 
#ifndef SOS
  jobsModel(p);               /* Basic problem definition */
#else
  jobsModelb(p);              /* Formulation using SOS */
#endif
  jobsSolve(p);               /* Solve and print solution */
  return 0;     
}

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

void jobsModelb(XPRBprob &p)   /**** 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",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(XPRBnewname("delta%d%d",j+1,t+1),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=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(p.newCtr("OBJ", 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=0;
  for(t=0;t<(NT-DUR[j]+1);t++)  le += (t+1)*delta[j][t];
  set[j] = p.newSos("sosj",XPRB_S1,le);
 } 

/****OUTPUT****/
 p.print();                     /* Print out the problem definition */ 
 p.exportProb(XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 


Back to examples browserPrevious exampleNext example