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)
  • 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.cxx, xbexpl1i.cxx, xbexpl2.cxx, xbcutex.cxx, xbqpr12.cxx, xbairport.cxx, xbcontr1.cxx, xbcontr2.cxx, xbcontr2s.cxx
Data file(s): durations.dat


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 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(void);       /* Basic model formulation */
void jobsModelb(void);      /* Model using SOS */
void jobsSolve(void);       /* Solving and solution printing */

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

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

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

void jobsModelb(void)         /**** 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 */ 
} 


xbexpl1i.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

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

  (c) 2008 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(void);        /* Read data from file  */
void jobsModel(void);       /* Basic model formulation */
void jobsSolve(void);       /* Solving and solution printing */

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

void readData()
{ 
 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()
{
 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();                   /* Solve the problem */

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

/*************************************************************************/
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(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) 
{         
 readData();                     /* Read in the data */
 jobsModel();                    /* Define and solve the problem */
 return 0;     
}


xbexpl2.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

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

  (c) 2008 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 */

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

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

void modTrans()
{
 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()
{
 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)
{
 readData();            /* Data input from file */
 modTrans();            /* Formulate and solve the problem */
 
 return 0;
} 

xbcutex.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

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

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

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

using namespace std;
using namespace ::dashoptimization;

#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) */ 
 
void jobsModel(void);       /* Basic model formulation */
void jobsSolve(void);       /* Solving and solution printing */

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

int XPRS_CC usrcme(XPRSprob oprob, void* vd)
{
 XPRBcut ca[2];
 int num;
 int i=0;
 XPRBprob *bprob;

/* 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. */
 
 bprob = (XPRBprob*)vd;
 bprob->beginCB(oprob);
 XPRSgetintattrib(oprob, XPRS_NODES, &num);
 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);
  cout << "Adding constraints:" << endl;
  for(i=0;i<2;i++) ca[i].print();
  if(bprob->addCuts(ca,2)) cout << "Problem with adding cuts." << endl;
 }
 bprob->endCB();
 return 0;                      /* Call this function once per node */
}

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

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

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

void jobsSolve()             
{ 
 int j,t,statmip; 
 XPRSprob oprob;

 oprob = p.getXPRSprob();
 XPRSsetintcontrol(oprob,XPRS_HEURSTRATEGY,0);
 XPRSsetintcontrol(oprob,XPRS_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 */
 XPRSsetcbcutmgr(oprob,usrcme,&p);

 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) 
{          
  jobsModel();                   /* Basic problem definition */
  jobsSolve();                   /* Solve and print solution */
  return 0;     
}



xbqpr12.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

  file xbqpr12.cxx
  ````````````````
  Small Quadratic Programming example.
       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
      author: S.Heipcke, Jan. 2000, rev. Mar. 2011
********************************************************/

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

using namespace std;
using namespace ::dashoptimization;

#define NXPRBvar 4

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

int main(int argc, char **argv)
{
 XPRBctr c;
 XPRBexpr le, qobj;
 XPRBvar x[NXPRBvar];
 int i;
 XPRBprob p("QPr12");     	/* Initialize a new problem in BCL */

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

/****OBJECTIVE****/
		                  /* Define the objective function */
 qobj = x[0] + sqr(x[0])  +2*x[0]*x[1]  + 2*sqr(x[1])  + sqr(x[3]);
 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(XPRB_MPS,"QPr12");  /* Output the matrix in MPS format */
 p.exportProb(XPRB_LP,"QPr12");   /* Output the matrix in LP format */
  
 p.setSense(XPRB_MINIM);      	  /* Choose the sense of the optimization */   
 p.lpOptimize("");                /* Solve the QP-problem */

 cout << "Objective function value: " << p.getObjVal() << endl;
 for(i=0;i<NXPRBvar;i++)
  cout << x[i].getName() << ": " << x[i].getSol() << ", ";
 cout << endl;
 
 return 0;
}

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

  file xbairport.cxx
  ``````````````````
  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
      author: S.Heipcke, June 2008, rev. Mar. 2011
********************************************************/

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

using namespace std;
using namespace ::dashoptimization;

#define N 42

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 main(int argc, char **argv)
{
 int i,j;
 XPRBvar x[N],y[N];
 XPRBexpr qe;
 XPRBctr cobj, c;
 XPRBprob prob("airport");              // Initialize a new problem in BCL

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

/****OBJECTIVE****/
// Minimize the total distance between all points
//  sum(i in 1..N-1,j in i+1..N) ((x(i)-x(j))^2+(y(i)-y(j))^2)
 qe=0;
 for(i=0;i<N-1;i++)
  for(j=i+1;j<N;j++) qe+= sqr(x[i]-x[j])+sqr(y[i]-y[j]);
 cobj = prob.newCtr("TotDist", qe);
 prob.setObj(cobj);                     // Set objective function 

/**** CONSTRAINTS ****/
// All points within given distance of their target location
//  (x(i)-CX(i))^2+(y(i)-CY(i))^2 <= R(i)
 for(i=0;i<N;i++)
  c = prob.newCtr("LimDist", sqr(x[i]-CX[i])+sqr(y[i]-CY[i]) <= R[i]);
 
/****SOLVING + OUTPUT****/
 prob.setSense(XPRB_MINIM);             // Choose the sense of optimization
 
/* Problem printing and matrix output: */
/*
 prob.print(); 
 prob.exportProb(XPRB_MPS, "airport");
 prob.exportProb(XPRB_LP, "airport");
*/

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

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

 return 0;
}  

xbcontr1.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

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

  (c) 2008 Fair Isaac Corporation
      author: S.Heipcke, Jan. 2000, rev. Oct. 2010
********************************************************/

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

using namespace std;
using namespace ::dashoptimization;

#define District 6               /* Number of districts */
#define 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 */
 
/***********************************************************************/

int main(int argc, char **argv)
{
 int d,c;
 XPRBexpr l1,l2,lobj;
 XPRBvar x[District][Contract];  /* Variables indicating whether a project 
                                    is chosen */
 XPRBvar y[District][Contract];  /* Quantities allocated to contractors */
 int i, ncol, len, stat, offset;
 double *sol, val;
 char *names;
 XPRSprob op;
 XPRBprob p("Contr1");                /* Initialize a new problem in BCL */
 
/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = p.newVar(XPRBnewname("x_d%dc%d",d+1,c+1),XPRB_BV);
   y[d][c] = p.newVar(XPRBnewname("q_d%dc%d",d+1,c+1),XPRB_SC,0,OUTPUT[d]);
   y[d][c].setLim(5);
  } 

/****OBJECTIVE****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   lobj += COST[d]*y[d][c];   
     
 p.setObj(p.newCtr("OBJ",lobj));      /* Set the objective function */
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  l1=0;
  l2=0;  
  for(d=0;d<District;d++)
  {
   l1 += y[d][c];
   l2 += x[d][c];
  }
  p.newCtr("Size", l1 >= 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=0;
  for(c=0;c<Contract;c++)
   l1 += y[d][c];
  p.newCtr("Output", l1 <= 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****/
 p.loadMat();                   /* Load the matrix explicitly */
 op = p.getXPRSprob();          /* Retrieve the Optimizer problem */
 XPRSchgobjsense(op, XPRS_OBJ_MINIMIZE);  /* Set sense to minimization */
 XPRSmipoptimize(op, "");       /* Solve the MIP problem */

 XPRSgetintattrib(op, XPRS_MIPSTATUS, &stat);
                                /* Get the global (MIP) status */
 if((stat==XPRS_MIP_SOLUTION) || (stat==XPRS_MIP_OPTIMAL))
 {                              /* Test whether an integer solution was found */
  XPRSgetdblattrib(op, XPRS_MIPOBJVAL, &val);   
  cout << "Objective: " << val << endl;
  XPRSgetintattrib(op, XPRS_ORIGINALCOLS, &ncol); 
  sol = new double[ncol];
  XPRSgetmipsol(op, sol, NULL); /* Get the primal solution values */
  XPRSgetnamelist(op, 2, NULL, 0, &len, 0, ncol-1);    
                        /* Get number of bytes required for retrieving names */
  names = new char[len];
  XPRSgetnamelist(op, 2, names, len, NULL, 0, ncol-1); 
                                /* Get the variable names */
  offset=0;
  for(i=0; i<ncol; i++) {       /* Print out the solution */
   if(sol[i]!=0)
    cout << names+offset << ": " << sol[i] << ", ";   
   offset += strlen(names+offset)+1;
  }     
  cout << endl;  
 }

 return 0;
} 

xbcontr2.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

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

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

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

using namespace std;
using namespace ::dashoptimization;

#define District 6               /* Number of districts */
#define 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 */
 
/***********************************************************************/

void XPRS_CC printsolution(XPRSprob oprob, void *vp)
{
 int num, d, c;
 XPRBprob *bprob;
 XPRBvar y;
 
 bprob = (XPRBprob *)vp;
 bprob->beginCB(oprob);
 XPRSgetintattrib(oprob, XPRS_MIPSOLS, &num); /* Get number of the solution */
 bprob->sync(XPRB_XPRS_SOL);                  /* Update BCL solution values */
 cout << "Solution " << num << ": Objective value: " << bprob->getObjVal() << endl; 

 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   y = bprob->getVarByName(XPRBnewname("q_d%dc%d",d+1,c+1));
   if( (y.getColNum()>-1) && (y.getSol() != 0))
    cout << y.getName() << ": " << y.getSol() << endl; 
  }
  
 bprob->endCB();
}

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

int main(int argc, char **argv)
{
 int d,c;
 XPRBexpr l1,l2,lobj;
 XPRBvar x[District][Contract];  /* Variables indicating whether a project 
                                    is chosen */
 XPRBvar y[District][Contract];  /* Quantities allocated to contractors */
 XPRBprob p("Contr2");           /* Initialize a new problem in BCL */
 
/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = p.newVar(XPRBnewname("x_d%dc%d",d+1,c+1),XPRB_BV);
   y[d][c] = p.newVar(XPRBnewname("q_d%dc%d",d+1,c+1),XPRB_SC,0,OUTPUT[d]);
   y[d][c].setLim(5);
  } 

/****OBJECTIVE****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   lobj += COST[d]*y[d][c];   
     
 p.setObj(p.newCtr("OBJ",lobj));       /* Set the objective function */
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  l1=0;
  l2=0;  
  for(d=0;d<District;d++)
  {
   l1 += y[d][c];
   l2 += x[d][c];
  }
  p.newCtr("Size", l1 >= 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=0;
  for(c=0;c<Contract;c++)
   l1 += y[d][c];
  p.newCtr("Output", l1 <= 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****/
 XPRSsetcbintsol(p.getXPRSprob(), printsolution, &p);
                                /* Define an integer solution callback */
 p.mipOptimize("");             /* Solve the MIP problem */

 return 0;
} 

xbcontr2s.cxx
/********************************************************
  Xpress-BCL C++ Example Problems
  ===============================

  file xbcontr2s.cxx
  ``````````````````
  Contract allocation example.
  Combining BCL problem input with problem solving 
  and callbacks in Xpress-Optimizer.
  -- Single MIP thread --

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

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

using namespace std;
using namespace ::dashoptimization;

#define District 6               /* Number of districts */
#define 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 */
 
/***********************************************************************/

void XPRS_CC printsolution(XPRSprob oprob, void *vp)
{
 int num, d, c;
 XPRBprob *bprob;
 XPRBvar y;
 
 bprob = (XPRBprob *)vp;
 XPRSgetintattrib(oprob, XPRS_MIPSOLS, &num); /* Get number of the solution */
 bprob->sync(XPRB_XPRS_SOL);                  /* Update BCL solution values */
 cout << "Solution " << num << ": Objective value: " << bprob->getObjVal() << endl; 

 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   y = bprob->getVarByName(XPRBnewname("q_d%dc%d",d+1,c+1));
   if( (y.getColNum()>-1) && (y.getSol() != 0))
    cout << y.getName() << ": " << y.getSol() << endl; 
  }
}

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

int main(int argc, char **argv)
{
 int d,c;
 XPRBexpr l1,l2,lobj;
 XPRBvar x[District][Contract];  /* Variables indicating whether a project 
                                    is chosen */
 XPRBvar y[District][Contract];  /* Quantities allocated to contractors */
 XPRBprob p("Contr2");           /* Initialize a new problem in BCL */
 
/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = p.newVar(XPRBnewname("x_d%dc%d",d+1,c+1),XPRB_BV);
   y[d][c] = p.newVar(XPRBnewname("q_d%dc%d",d+1,c+1),XPRB_SC,0,OUTPUT[d]);
   y[d][c].setLim(5);
  } 

/****OBJECTIVE****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   lobj += COST[d]*y[d][c];   
     
 p.setObj(p.newCtr("OBJ",lobj));       /* Set the objective function */
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  l1=0;
  l2=0;  
  for(d=0;d<District;d++)
  {
   l1 += y[d][c];
   l2 += x[d][c];
  }
  p.newCtr("Size", l1 >= 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=0;
  for(c=0;c<Contract;c++)
   l1 += y[d][c];
  p.newCtr("Output", l1 <= 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****/
 XPRSsetintcontrol(p.getXPRSprob(), XPRS_MIPTHREADS, 1);
    /* Desactivate parallel MIP (for synchronization of BCL and Optimizer) */
 XPRSsetcbintsol(p.getXPRSprob(), printsolution, &p);
                                /* Define an integer solution callback */
 p.mipOptimize("");             /* Solve the MIP problem */

 return 0;
}