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;
} 

© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.