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.c version BASIC)
  • using variable arrays and constraint templates (xbexpl1.c versions ARRAY and ARRAYC)
  • definition of SOS-1 (xbexpl1 version SOS)
  • data input from file, index sets (xbexpl1i)
  • user error handling, output redirection (xbexpl3)
  • solving multiple scenarios of a transportation problem in parallel (xbexpl2: standard, single thread version; xbscenar: defining multiple problems, each in a separate thread)
  • 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.c, xbexpl1i.c, xbexpl3.c, xbexpl2.c, xbscenar.c, xbcutex.c, xbqpr12.c, xbairport.c, xbcontr1.c, xbcontr2.c, xbcontr2s.c
Data file(s): durations.dat


xbexpl1.c
/********************************************************
  BCL Example Problems
  ====================

  file xbexpl1.c
  ``````````````
  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 <stdio.h>
#include "xprb.h"

/**************************************************************************/
/* Define *one* of the following options to try out different problem     */
/* formulations:                                                          */
/**************************************************************************/
#define BASIC
#undef ARRAYC
#undef SOS
#undef ARRAY
/**************************************************************************/

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

/**** DATA ****/
double DUR[] = {3,4,2,2};    /* Durations of jobs   */ 
/*{4,2,3,4};
  {5,1,1,6};
  {5,5,4,4}; */
#ifdef ARRAY
XPRBarrvar start;            /* Start times of jobs  */ 
XPRBarrvar delta[NJ];        /* Sets of binaries for start times */  
#else
XPRBvar start[NJ];           /* Start times of jobs  */ 
XPRBvar delta[NJ][NT];       /* Binaries for start times */  
#endif

XPRBsos set[NJ];             /* Sets regrouping start times for jobs */

XPRBvar z;                   /* Maximum completion time (makespan) */ 

XPRBprob prob;               /* BCL problem */
 
void jobs_model(void);       /* Basic model formulation */
void jobs_modela(void);      /* Model using arrays of variables for some
                                constraints  */
void jobs_modelb(void);      /* Model using SOS */
void jobs_modelc(void);      /* Model using arrays of variables for
                                all variables */
void jobs_solve(void);        /* Solving and solution printing */
             
/*************************************************************************/

void jobs_model(void)
{
 XPRBctr ctr;
 int j,t;

 prob=XPRBnewprob("Jobs");   /* Initialization */ 

/****VARIABLES****/
                             /* Create start time variables */
 for(j=0;j<NJ;j++) start[j] = XPRBnewvar(prob,XPRB_PL,"start",0,NT);
 z = XPRBnewvar(prob,XPRB_PL,"z",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] = XPRBnewvar(prob,XPRB_BV,XPRBnewname("delta%d%d",j+1,t+1),0,1);

/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)           /* Calculate maximal completion time  */
  XPRBnewprec(prob,"Makespan",start[j],DUR[j],z); 
 XPRBnewprec(prob,"Prec",start[0],DUR[0],start[2]);
                             /* Precedence relation between jobs */

 for(j=0;j<NJ;j++)           /* Linking start times and binaries  */ 
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("Link_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],t+1); 
  XPRBaddterm(ctr,start[j],-1); 
 } 
               
 for(j=0;j<NJ;j++)           /* One unique start time for each job  */
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("One_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],1); 
  XPRBaddterm(ctr,NULL,1); 
 }      
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob,"OBJ",XPRB_N); 
 XPRBaddterm(ctr,z,1); 
 XPRBsetobj(prob,ctr);       /* Set objective function */ 

/****BOUNDS****/
 for(j=0;j<NJ;j++) XPRBsetub(start[j],NT-DUR[j]+1); 
                /* upper bounds on start time variables */

/****OUTPUT****/
 XPRBprintprob(prob);        /* Print out the problem definition */ 
 XPRBexportprob(prob,XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 

/*************************************************************************/
void jobs_solve(void)             
{ 
 int statmip; 
 int j;
 int t;
#ifndef SOS
 for(j=0;j<NJ;j++)    
  for(t=0;t<NT-DUR[j]+1;t++)
   XPRBsetvardir(delta[j][t],XPRB_PR,10*(t+1)); 
          /* Give highest priority to variables for earlier start times */
#else
 for(j=0;j<NJ;j++)    
  XPRBsetsosdir(set[j],XPRB_DN,0); 
          /* First branch downwards on sets */
#endif

 XPRBsetsense(prob,XPRB_MINIM);
 XPRBmipoptimize(prob,"");        /* Solve the problem as MIP */
 statmip = XPRBgetmipstat(prob);  /* Get the MIP problem status */    
              
 if((statmip == XPRB_MIP_SOLUTION) || (statmip == XPRB_MIP_OPTIMAL))
                                  /* An integer solution has been found */
 {  
  printf("Objective: %g\n",XPRBgetobjval(prob)); 
  for(j=0;j<NJ;j++) 
  {                               /* Print the solution for all start times */
   printf("%s: %g\n",XPRBgetvarname(start[j]), XPRBgetsol(start[j])); 
#ifdef ARRAY
   XPRBprintarrvar(delta[j]);
#else
   for(t=0;t<NT-DUR[j]+1;t++) 
    printf("%s: %g, ", XPRBgetvarname(delta[j][t]), XPRBgetsol(delta[j][t]));
   printf("\n");
#endif       
  }
 } 
}

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

int main(int argc, char **argv) 
{          
#ifdef BASIC
  jobs_model();               /* Basic problem definition */
#endif                 
#ifdef ARRAYC
  jobs_modela();              /* Formulation using arrays for some 
                                 constraints */
#endif
#ifdef SOS
  jobs_modelb();              /* Formulation using SOS */
#endif
#ifdef ARRAY
  jobs_modelc();              /* Formulation using arrays of variables */
#endif
  jobs_solve();               /* Solve and print solution */
  return 0;     
}

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

    /**** Formulation using arrays in constraint definition ****/
void jobs_modela(void) 
{
 XPRBctr ctr;
 XPRBarrvar v;
 int j,t;

 prob=XPRBnewprob("Jobs");          /* Initialization */ 

/****VARIABLES****/
                                    /* Create start time variables */
 for(j=0;j<NJ;j++) start[j] = XPRBnewvar(prob,XPRB_PL,"start",0,NT);
 z = XPRBnewvar(prob,XPRB_PL,"z",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] = XPRBnewvar(prob,XPRB_BV,XPRBnewname("delta%d%d",j+1,t+1),0,1);

             
/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)                  /* Calculate maximal completion time  */
  XPRBnewprec(prob,"Makespan",start[j],DUR[j],z); 
 XPRBnewprec(prob,"Prec",start[0],DUR[0],start[2]);
                                    /* Precedence relation between jobs  */

 for(j=0;j<NJ;j++)   
 {
  double ind[NT];  
  v = XPRBstartarrvar(prob,NT-(int)(DUR[j])+2,"v1");  /* Define an array of size
                                                NT-DUR[j]+2 */
  for(t=0;t<(NT-(int)(DUR[j])+1);t++)   
  {
   XPRBapparrvarel(v,delta[j][t]);  /* Add a binary variable to the array */
   ind[t]=t+1;                      /* Add a coefficient */
  }
  XPRBapparrvarel(v,start[j]);      /* Add a continuous var. to the array */
  XPRBendarrvar(v);                 /* Terminate definition of the array  */
  ind[NT-(int)DUR[j]+1]=-1;         /* Add another coefficient */
  XPRBnewarrsum(prob,XPRBnewname("Link_%d",j+1),v,ind,XPRB_E,0);  
                                    /* Establish sum constraint using array v */
  XPRBdelarrvar(v);                 /* Free the memory allocated to the array */
 }                                  /* ... and the table of coefficients  */ 
              
 for(j=0;j<NJ;j++)                  /* One unique start time for each job  */
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("One_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],1); 
  XPRBaddterm(ctr,NULL,1); 
 }         
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob,"OBJ",XPRB_N); 
 XPRBaddterm(ctr,z,1); 
 XPRBsetobj(prob,ctr);              /* Select objective function */ 

/****BOUNDS****/
 for(j=0;j<NJ;j++) XPRBsetub(start[j],NT-DUR[j]+1); 
                                    /* Upper bounds on start time variables */

/****OUTPUT****/
 XPRBprintprob(prob);               /* Print out the problem definition */ 
 XPRBexportprob(prob,XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 

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

    /**** SOS-formulation ****/
void jobs_modelb(void) 
{
 XPRBctr ctr;
 int j,t;

 prob=XPRBnewprob("Jobs");          /* Initialization */ 

/****VARIABLES****/
                                    /* Create start time variables */
 for(j=0;j<NJ;j++) start[j] = XPRBnewvar(prob,XPRB_PL,"start",0,NT);
 z = XPRBnewvar(prob,XPRB_PL,"z",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] = XPRBnewvar(prob,XPRB_PL,XPRBnewname("delta%d%d",j+1,t+1),0,1);

/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)                  /* Calculate maximal completion time  */
  XPRBnewprec(prob,"Makespan",start[j],DUR[j],z); 
 XPRBnewprec(prob,"Prec",start[0],DUR[0],start[2]);
                                    /* Precedence relation between jobs  */

 for(j=0;j<NJ;j++)                  /* Linking start times and binaries  */ 
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("Link_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],t+1); 
  XPRBaddterm(ctr,start[j],-1); 
 } 
              
 for(j=0;j<NJ;j++)                  /* One unique start time for each job  */
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("One_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],1); 
  XPRBaddterm(ctr,NULL,1); 
 }         
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob,"OBJ",XPRB_N); 
 XPRBaddterm(ctr,z,1); 
 XPRBsetobj(prob,ctr);              /* Select objective function */ 


/****BOUNDS****/
 for(j=0;j<NJ;j++) XPRBsetub(start[j],NT-DUR[j]+1); 
                                    /* Upper bounds on start time variables */

/****SETS****/
 for(j=0;j<NJ;j++)  
 {
  set[j] = XPRBnewsos(prob,"sosj",XPRB_S1);
  for(t=0;t<(NT-DUR[j]+1);t++)
   XPRBaddsosel(set[j],delta[j][t],t+1);
 } 

/****OUTPUT****/
 XPRBprintprob(prob);               /* Print out the problem definition */ 
 XPRBexportprob(prob,XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 

/*************************************************************************/
#ifdef ARRAY
void jobs_modelc(void)
{
 XPRBctr ctr;
 int j;

 prob=XPRBnewprob("Jobs");          /* Initialization */ 

/****VARIABLES****/
                                    /* Create a table of start time variables */
 start = XPRBnewarrvar(prob,NJ,XPRB_PL,"start",0,NT);
 z = XPRBnewvar(prob,XPRB_PL,"z",0,NT);  /* Declare the makespan variable */

 for(j=0;j<NJ;j++)                  /* Declare a set of binaries for each job */
  delta[j] = XPRBnewarrvar(prob,(NT-(int)(DUR[j])+1),XPRB_BV,XPRBnewname("delta%d",j+1),0,1);

/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)                  /* Calculate maximal completion time  */
  XPRBnewprec(prob,"Makespan",start[j],DUR[j],z); 
 XPRBnewprec(prob,"Prec",start[0],DUR[0],start[2]);
                                    /* Precedence relation between jobs  */

/* Alternative constraint formulation: (linking start times and binaries) */
/*
 for(j=0;j<NJ;j++)      
 { 
  int t;
  double c[NT];

  ctr = XPRBnewctr(prob,XPRBnewname("Link_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) c[t]=t+1; 
  XPRBaddarrterm(ctr,delta[j],c); 
  XPRBaddterm(ctr,start[j],-1); 
 } 
*/

 for(j=0;j<NJ;j++)                  /* Linking start times and binaries  */
 { 
  ctr = XPRBnewsumc(prob,XPRBnewname("Link%d",j+1),delta[j],1,XPRB_E,0);
  XPRBaddterm(ctr,start[j],-1); 
 } 
               
 for(j=0;j<NJ;j++)                  /* One unique start time for each job  */
  XPRBnewsum(prob,"One",delta[j],XPRB_E,1);     
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob,"OBJ",XPRB_N); 
 XPRBaddterm(ctr,z,1); 
 XPRBsetobj(prob,ctr);              /* Select objective function */ 

/****BOUNDS****/
 for(j=0;j<NJ;j++) XPRBsetub(start[j],NT-DUR[j]+1); 
                                    /* Upper bounds on start time variables */

/****SETS****/
/* Alternative SOS formulation: define delta as continuous variables! */
/* 
 for(j=0;j<NJ;j++)
  XPRBnewsosrc(prob,"sosj",XPRB_S1,delta[j],
               XPRBgetbyname(prob,XPRBnewname("Link_%d",j+1),XPRB_PL)); */
        /* Create an SOS-1 for each job with a reference row from ctr.s Link */ 

/****OUTPUT****/
 XPRBprintprob(prob);               /* Print out the problem definition */ 
 XPRBexportprob(prob,XPRB_MPS,"expl1");  /* Output matrix to MPS file */ 
} 
#endif

xbexpl1i.c
/********************************************************
  BCL Example Problems
  ====================

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

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

#include <stdio.h>
#include <stdlib.h>
#include "xprb.h"

#define MAXNJ 4              /* Maximum 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   */ 

XPRBidxset Jobs;	     /* Job names */
XPRBvar *start;              /* Start times of jobs  */ 
XPRBvar **delta;             /* Binaries for start times */  
XPRBvar z;                   /* Maximum completion time (makespan) */ 
XPRBprob prob;               /* BCL problem */
 
void read_data(void);        /* Read data from file  */
void jobs_model(void);       /* Model formulation */
void jobs_solve(void);       /* Solving and solution printing */
 
/*************************************************************************/

void read_data(void)
{ 
 char name[100];
 FILE *datafile;
                             /* Create a new index set */
 Jobs = XPRBnewidxset(prob, "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 */
  XPRBaddidxel(Jobs,name);   /* Add job to the index set */
  NJ++;
 }
 fclose(datafile);           /* Close the input file */
 printf("Number of jobs read: %d\n", XPRBgetidxsetsize(Jobs));
}

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

void jobs_model(void)
{
 XPRBctr ctr;
 int j,t; 

/****VARIABLES****/
                             /* Create start time variables (incl. bounds) */
 start = (XPRBvar *)malloc(NJ * sizeof(XPRBvar)); 
 if(start==NULL) 
 { printf("Not enough memory for 'start' variables.\n"); exit(0); }
 for(j=0;j<NJ;j++) start[j] = XPRBnewvar(prob,XPRB_PL,"start",0,NT-DUR[j]+1);
 z = XPRBnewvar(prob,XPRB_PL,"z",0,NT);  /* Declare the makespan variable */

                             /* Declare binaries for each job  */
 delta = (XPRBvar **)malloc(NJ * sizeof(XPRBvar*));
 if(delta==NULL)
 { printf("Not enough memory for 'delta' variables.\n"); exit(0); }
 for(j=0;j<NJ;j++)
 {
  delta[j] = (XPRBvar *)malloc(NT* sizeof(XPRBvar));
  if(delta[j]==NULL)
  { printf("Not enough memory for 'delta_j' variables.\n"); exit(0); }
  for(t=0;t<(NT-DUR[j]+1);t++)
   delta[j][t] = XPRBnewvar(prob,XPRB_BV,
                  XPRBnewname("delta%s_%d",XPRBgetidxelname(Jobs,j),t+1),0,1);
 }
 
/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)           /* Calculate maximal completion time  */
  XPRBnewprec(prob,"Makespan",start[j],DUR[j],z); 
 XPRBnewprec(prob,"Prec",start[0],DUR[0],start[2]);
                             /* Precedence relation between jobs */

 for(j=0;j<NJ;j++)           /* Linking start times and binaries  */ 
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("Link_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],t+1); 
  XPRBaddterm(ctr,start[j],-1); 
 }
              
 for(j=0;j<NJ;j++)           /* One unique start time for each job  */
 { 
  ctr = XPRBnewctr(prob,XPRBnewname("One_%d",j+1),XPRB_E); 
  for(t=0;t<(NT-DUR[j]+1);t++) XPRBaddterm(ctr,delta[j][t],1); 
  XPRBaddterm(ctr,NULL,1); 
 }      
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob,"OBJ",XPRB_N); 
 XPRBaddterm(ctr,z,1); 
 XPRBsetobj(prob,ctr);       /* Set objective function */ 

 jobs_solve();               /* Solve the problem */

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

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

void jobs_solve(void)
{
 int j,t,statmip; 

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

 XPRBsetsense(prob,XPRB_MINIM);
 XPRBmipoptimize(prob,"");        /* Solve the problem as MIP */
 statmip = XPRBgetmipstat(prob);  /* Get the MIP problem status */    
              
/****SOLUTION PRINTING****/
 if((statmip == XPRB_MIP_SOLUTION) || (statmip == XPRB_MIP_OPTIMAL))
                                  /* An integer solution has been found */
 {  
  printf("Objective: %g\n",XPRBgetobjval(prob)); 
  for(j=0;j<NJ;j++) 
  {                               /* Print the solution for all start times */
   printf("%s: %g\n",XPRBgetvarname(start[j]), XPRBgetsol(start[j])); 
   for(t=0;t<NT-DUR[j]+1;t++) 
    printf("%s: %g, ", XPRBgetvarname(delta[j][t]), XPRBgetsol(delta[j][t]));
   printf("\n");
  }
 } 
}

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

int main(int argc, char **argv) 
{          
 prob=XPRBnewprob("Jobs");    /* Initialization */ 
 read_data();                 /* Read data from file */
 jobs_model();                /* Define and solve the problem */
 return 0;     
}


xbexpl3.c
/********************************************************
  BCL Example Problems
  ====================

  file xbexpl3.c
  ``````````````
  User error handling.

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

#include <stdio.h>
#include <setjmp.h>
#include <string.h>
#include "xprb.h"

/* This small, infeasible example shows how the error handling and all 
   printed messages can be intercepted by the user's program. This is done 
   by defining the corresponding BCL callback functions and changing 
   the error handling flag. */

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

jmp_buf model_failed;

void modexpl3(XPRBprob prob)
{
 XPRBvar x[3];
 XPRBctr ctr[2], cobj;
 int i;

 for(i=0;i<2;i++) x[i]=XPRBnewvar(prob,XPRB_UI,XPRBnewname("x_%d",i),0,100);

                /* Create the constraints:
                   C1: 2x0 + 3x1 >= 41
                   C2:  x0 + 2x1  = 13 */
 ctr[0]=XPRBnewctr(prob,"C1",XPRB_G);
 XPRBaddterm(ctr[0],x[0],2);
 XPRBaddterm(ctr[0],x[1],3);
 XPRBaddterm(ctr[0],NULL,41);     

 ctr[1]=XPRBnewctr(prob,"C2",XPRB_E);
 XPRBaddterm(ctr[1],x[0],1);
 XPRBaddterm(ctr[1],x[1],2);
 XPRBaddterm(ctr[1],NULL,13);    

/* Uncomment the following line to cause an error in the model that
   triggers the user error handling: */

/* x[2]=XPRBnewvar(prob,XPRB_UI,"x_2",10,1); */
 
                /* Objective: minimize x0+x1 */
 cobj = XPRBnewctr(prob,"OBJ",XPRB_N); 
 for(i=0;i<2;i++) XPRBaddterm(cobj,x[i],1); 
 XPRBsetobj(prob,cobj);          /* Select objective function */ 
 XPRBsetsense(prob,XPRB_MINIM);  /* Set objective sense to minimization */

 XPRBprintprob(prob);            /* Print current problem definition */

 XPRBlpoptimize(prob,"");        /* Solve the LP */
 XPRBprintf(prob,"problem status: %d  LP status: %d  MIP status: %d\n",
    XPRBgetprobstat(prob),XPRBgetlpstat(prob),XPRBgetmipstat(prob));

/* This problem is infeasible, that means the following command will fail.
   It prints a warning if the message level is at least 2 */
   
 XPRBprintf(prob,"Objective: %g\n",XPRBgetobjval(prob));

 for(i=0;i<2;i++)                /* Print solution values */ 
  XPRBprintf(prob,"%s:%g, ", XPRBgetvarname(x[i]), XPRBgetsol(x[i]));
 XPRBprintf(prob,"\n");
}

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

/**** User error handling function ****/
void XPRB_CC usererror(XPRBprob prob, void *vp, int num, int type, 
                       const char *t)
{  
 printf("BCL error %d: %s\n", num, t);
 if(type==XPRB_ERR) longjmp(model_failed,1);
}

/**** User printing function ****/
void XPRB_CC userprint(XPRBprob prob, void *vp, const char *msg)   
{
 static int rtsbefore=1;

    /* Print 'BCL output' whenever a new output line starts,
       otherwise continue to print the current line. */ 
 if(rtsbefore)
  printf("BCL output: %s", msg);
 else
  printf("%s",msg);
 rtsbefore=(msg[strlen(msg)-1]=='\n');
}

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

int main(int argc, char **argv)
{
 XPRBprob prob;

 XPRBseterrctrl(0);         /* Switch to error handling by the user's program */

 XPRBsetmsglevel(NULL,2);   /* Set the printing flag. Try other values:
                                0 - no printed output, 1 - only errors,
                                2 - errors and warnings, 3 - all messages */
 XPRBdefcbmsg(NULL,userprint, NULL);  
                            /* Define the printing callback function */

 if((prob=XPRBnewprob("Expl3"))==NULL)
 {                          /* Initialize a new problem in BCL */
  fprintf(stderr,"I cannot create the problem\n");
  return 1;
 }
 else
  if(setjmp(model_failed))
  {
   fprintf(stderr,"I cannot build the problem\n");
   XPRBdelprob(prob);
   XPRBdefcberr(prob,NULL, NULL);
   return 1;
  }
  else
  {
   XPRBdefcberr(prob,usererror, NULL);
   modexpl3(prob);          /* Formulate and solve the problem */
   XPRBdefcberr(prob,NULL, NULL);
   return 0;
  }
} 


xbexpl2.c
/********************************************************
  BCL Example Problems
  ====================

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

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

#include <stdio.h>
#include <stdlib.h>
#include "xprb.h"

#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) */

XPRBidxset Suppliers;            /* Set of suppliers */
XPRBidxset 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 prob)
{
 XPRBctr *av, *de, cobj;
 int s,c,a;
 XPRBvar *x;
 
/****VARIABLES****/
 x = (XPRBvar *)malloc(NArc * sizeof(XPRBvar)); 
 if(x==NULL) printf("Allocating memory for variables failed.");
 for(a=0; a<NArc; a++) 
  x[a]=XPRBnewvar(prob,XPRB_PL,"x",0,XPRB_INFINITY);
     
/****OBJECTIVE****/
 cobj = XPRBnewctr(prob,"OBJ", XPRB_N); 
 for(a=0; a<NArc; a++)
  XPRBaddterm(cobj, x[a], COST[a].value);
 XPRBsetobj(prob,cobj);          /* Select objective function */ 

/****CONSTRAINTS****/
    /**** Create all constraints in a single loop ****/
                                 /* Initialize the constraints */
 av = (XPRBctr *)malloc(NSuppl * sizeof(XPRBctr)); 
 if(av==NULL) printf("Not enough memory for AV constraints.");
 de = (XPRBctr *)malloc(NCustom * sizeof(XPRBctr)); 
 if(de==NULL) printf("Not enough memory for DE constraints.");
 for(s=0; s<NSuppl; s++)
  av[s]=XPRBnewctr(prob,"Avail", XPRB_L);
 for(c=0; c<NCustom; c++)
  de[c]=XPRBnewctr(prob,"Demand", XPRB_G);

    /* Add elements (coefficients) to constraints one-by-one */
 for(a=0; a<NArc; a++)
 {
  XPRBaddterm(av[COST[a].suppl],x[a],1);
  XPRBaddterm(de[COST[a].custm],x[a],1);
 }

    /* Terminate the constraint definition */
 for(s=0; s<NSuppl; s++)
  XPRBaddterm(av[s],NULL,AVAIL[s]);  
 for(c=0; c<NCustom; c++)
  XPRBaddterm(de[c],NULL,DEMAND[c]);  

/****SOLVING + OUTPUT****/
 XPRBexportprob(prob,XPRB_MPS,"trans");  /* Matrix output to MPS file */

 XPRBsetsense(prob,XPRB_MINIM);          /* Choose the sense of optimization */
 XPRBlpoptimize(prob,"");                /* Solve the LP-problem */
 printf("Objective: %g\n",XPRBgetobjval(prob));   /* Get objective value */

                     /* Print out the solution values for all arcs */
 for(a=0; a<NArc; a++)
 if(XPRBgetsol(x[a])>0)
  printf("%s (%g) -> %s (%g): %g\n",XPRBgetidxelname(Suppliers,COST[a].suppl),
    AVAIL[COST[a].suppl],
    XPRBgetidxelname(Customers,COST[a].custm), 
    DEMAND[COST[a].custm], XPRBgetsol(x[a]));  
}

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

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

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

        /* 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 = XPRBgetidxel(Suppliers, name);
  COST[NArc].custm = XPRBgetidxel(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 prob;

 prob=XPRBnewprob("Trans");    /* Initialize a new problem in BCL */
 readdata(prob);               /* Data input from file */
 modtrans(prob);               /* Formulate and solve the problem */
 
 return 0;
} 

xbscenar.c
/********************************************************
  BCL Example Problems
  ====================

  file xbscenar.c
  ```````````````
  Different demand scenarios implemented with 
  multiple threads.

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "xprb.h"

#define NSCENARIO 4              /* Number of demand scenarios */

#define MaxSuppliers 50          /* Max. number of suppliers */
#define MaxCustomers 50          /* Max. number of customers */
#define MaxArcs 100              /* Max. number of non-zero cost values */

#define DEMANDFILE XPRBDATAPATH "/trans/ex2dem"  
                                 /* Demand data file (name completed below) */
#define AVAILFILE XPRBDATAPATH "/trans/ex2avail.dat" 
                                 /* Supply data file */
#define COSTFILE XPRBDATAPATH "/trans/ex2cost.dat"   
                                 /* Cost data file */

struct Costarcs{
        int suppl;
        int custm;
        double value;
};

DWORD WINAPI trans(LPVOID param);
void XPRB_CC userprint(XPRBprob prob, void *file, const char *msg);   

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

/**********************/
/* Where things start */
/**********************/
int main(int argc,char *argv[])
{
 HANDLE tosolve[NSCENARIO];
 int i;

 XPRBinit();                     /* Initialize BCL */

 /* Start the building+solving in parallel */
 for(i=0;i<NSCENARIO;i++)
  tosolve[i]=CreateThread(NULL, 0, trans, (void *)(i+1),0 ,0);

 /* Wait for results */
 for(i=0;i<NSCENARIO;i++)
  WaitForSingleObject(tosolve[i], INFINITE);

 /* Clear up everything (not really required here since the program 
    terminates immediately afterwards) */
 XPRBfinish();
 return 0;
}

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

DWORD WINAPI trans(LPVOID param)
{
 double value;
 FILE *datafile, *outfile;
 char name[50], name1[100], name2[100];
 XPRBidxset Suppliers;            /* Set of suppliers */
 XPRBidxset Customers;            /* Set of customers */
 double AVAIL[MaxSuppliers];      /* Availability of products */
 double DEMAND[MaxCustomers];     /* Demand by customers */
 struct Costarcs COST[MaxArcs];   /* Cost per supplier-customer pair */
 int NSuppl=0,NCustom=0, NArc=0;  /* Actual numbers of suppliers, customers, 
                                     and arcs */
 XPRBctr *av, *de, cobj;
 int s,c,a;
 XPRBvar *x; 
 XPRBprob prob;

 sprintf(name, "Trans_%d", (int)param); 
 prob=XPRBnewprob(name);          /* Initialize a new problem in BCL */
 strcat(name, "_out.txt");
 outfile=fopen(name, "w");

 XPRBdefcbmsg(prob,userprint, outfile);  /* Redirect output to a file: comment
                                            this line out to get all display on
                                            screen */

        /* Create supplier and customer index sets */
 Suppliers=XPRBnewidxset(prob,"suppl",MaxSuppliers);
 Customers=XPRBnewidxset(prob,"custom",MaxCustomers);
 
        /* Read the demand data file for this problem */
 sprintf(name, "%s%d.dat", DEMANDFILE, (int)param);       
 datafile=fopen(name ,"r");
 while (XPRBreadlinecb(XPRB_FGETS, datafile, 200, "T,g", name1, &value) == 2)
  DEMAND[XPRBaddidxel(Customers,name1)]=value;
 fclose(datafile);
 NCustom = XPRBgetidxsetsize(Customers);

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

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


/****VARIABLES****/
 x = (XPRBvar *)malloc(NArc * sizeof(XPRBvar)); 
 if(x==NULL) printf("Allocating memory for variables failed.");
 for(a=0; a<NArc; a++) 
  x[a]=XPRBnewvar(prob,XPRB_PL,"x",0,XPRB_INFINITY);
     
/****OBJECTIVE****/
 cobj = XPRBnewctr(prob,"OBJ", XPRB_N); 
 for(a=0; a<NArc; a++)
  XPRBaddterm(cobj, x[a], COST[a].value);
 XPRBsetobj(prob,cobj);          /* Select objective function */ 

/****CONSTRAINTS****/
    /**** Create all constraints in a single loop ****/
                                 /* Initialize the constraints */
 av = (XPRBctr *)malloc(NSuppl * sizeof(XPRBctr)); 
 if(av==NULL) printf("Not enough memory for AV constraints.");
 de = (XPRBctr *)malloc(NCustom * sizeof(XPRBctr)); 
 if(de==NULL) printf("Not enough memory for DE constraints.");
 for(s=0; s<NSuppl; s++)
  av[s]=XPRBnewctr(prob,"Avail", XPRB_L);
 for(c=0; c<NCustom; c++)
  de[c]=XPRBnewctr(prob,"Demand", XPRB_G);

    /* Add elements (coefficients) to constraints one-by-one */
 for(a=0; a<NArc; a++)
 {
  XPRBaddterm(av[COST[a].suppl],x[a],1);
  XPRBaddterm(de[COST[a].custm],x[a],1);
 }

    /* Terminate the constraint definition */
 for(s=0; s<NSuppl; s++)
  XPRBaddterm(av[s],NULL,AVAIL[s]);  
 for(c=0; c<NCustom; c++)
  XPRBaddterm(de[c],NULL,DEMAND[c]);  

/****SOLVING + OUTPUT****/
 XPRBsetsense(prob,XPRB_MINIM);     /* Choose the sense of the optimization */
 XPRBlpoptimize(prob,"");           /* Solve the LP-problem */
 if(XPRBgetlpstat(prob) == XPRB_LP_OPTIMAL)
 {
  XPRBprintf(prob, "Problem %s Objective: %g\n", XPRBgetprobname(prob), 
             XPRBgetobjval(prob));
                                    /* Print objective value */

                     /* Print out the solution values for all arcs */
  for(a=0; a<NArc; a++)
  if(XPRBgetsol(x[a])>0)
   XPRBprintf(prob, "%s (%g) -> %s (%g): %g\n", 
     XPRBgetidxelname(Suppliers,COST[a].suppl),
     AVAIL[COST[a].suppl],
     XPRBgetidxelname(Customers,COST[a].custm), 
     DEMAND[COST[a].custm], XPRBgetsol(x[a]));  
 }
 else
  XPRBprintf(prob, "Problem %s is infeasible\n", XPRBgetprobname(prob));

 free(x);
 free(av);
 free(de);
 XPRBdelprob(prob);

 fclose(outfile);
 
 return 0;
}

void XPRB_CC userprint(XPRBprob prob, void *file, const char *msg)
{
    /* Print output of each example into a different file */ 
  fprintf((FILE *)file, "%s", msg);
}

xbcutex.c
/********************************************************
  BCL Example Problems
  ====================

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

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

#include <stdio.h>
#include "xprb.h"
#include "xprs.h"

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

/**** DATA ****/
double D[] = {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) */ 

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

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;
 XPRBbegincb(bprob, oprob);

 XPRSgetintattrib(oprob, XPRS_NODES, &num);
 if(num == 2) 
 {                                                 /* ca0: s_1+2 <= s_0 */
  ca[0] = XPRBnewcutprec(bprob, start[1], 2, start[0], 2); 
  ca[1] = XPRBnewcut(bprob, XPRB_L, 2);  /* ca1: 4*s_2 - 5.3*s_3 <= -17 */
  XPRBaddcutterm(ca[1], start[2], 4);
  XPRBaddcutterm(ca[1], start[3], -5.3);
  XPRBaddcutterm(ca[1], NULL, -17);
  printf("Adding constraints:\n");
  for(i=0;i<2;i++) XPRBprintcut(ca[i]);
  if(XPRBaddcuts(bprob, ca, 2)) printf("Problem with adding cuts.\n");
 }
 XPRBendcb(bprob);

 return 0;
}

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

void cmodel1(XPRBprob prob)
{
 XPRBctr ctr;
 int j,t;

/****VARIABLES****/
                            /* Create start time variables */
 for(j=0;j<NJ;j++) start[j] = XPRBnewvar(prob, XPRB_PL, "start", 0, NT);
                            /* Declare the makespan variable */
 z = XPRBnewvar(prob, XPRB_PL, "z", 0, NT);    

 for(j=0;j<NJ;j++)          /* Declare binaries for each job  */
  for(t=0;t<(NT-D[j]+1);t++)
   delta[j][t] = 
    XPRBnewvar(prob, XPRB_BV, XPRBnewname("delta%d%d",j+1,t+1), 0, 1);

/****CONSTRAINTS****/
 for(j=0;j<NJ;j++)          /* Calculate maximal completion time  */
  XPRBnewprec(prob, "C1", start[j], D[j], z); 
                            /* Precedence relation between jobs  */
 XPRBnewprec(prob, "C2", start[0], D[0], start[2]);    

 for(j=0;j<NJ;j++)          /* Linking start times and binaries  */ 
 { 
  ctr = XPRBnewctr(prob, XPRBnewname("C3_%d",j+1), XPRB_E); 
  for(t=0;t<(NT-D[j]+1);t++) XPRBaddterm(ctr, delta[j][t], t+1); 
  XPRBaddterm(ctr, start[j], -1); 
 } 
               
 for(j=0;j<NJ;j++)          /* One unique start time for each job  */
 { 
  ctr = XPRBnewctr(prob, XPRBnewname("C4_%d",j+1), XPRB_E); 
  for(t=0;t<(NT-D[j]+1);t++) XPRBaddterm(ctr, delta[j][t], 1); 
  XPRBaddterm(ctr, NULL, 1); 
 }      
              
/****OBJECTIVE****/
 ctr = XPRBnewctr(prob, "OBJ", XPRB_N); 
 XPRBaddterm(ctr, z, 1); 
 XPRBsetobj(prob, ctr);     /* Set objective function */ 

/****BOUNDS****/
 for(j=0;j<NJ;j++) XPRBsetub(start[j], NT-D[j]+1); 
                            /* Upper bounds on start time variables */
} 

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

void csolve(XPRBprob bprob)             
{ 
 int statmip; 
 int j;
 int t;
 XPRSprob oprob;

 oprob = XPRBgetXPRSprob(bprob);
 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 */

 XPRBsetsense(bprob, XPRB_MINIM);
 XPRBsetcutmode(bprob, 1);   /* Switch presolve off, enable cut manager */
 XPRSsetcbcutmgr(oprob, usrcme, bprob);
 XPRBmipoptimize(bprob, "");       /* Solve the problem as MIP */

 statmip = XPRBgetmipstat(bprob);  /* Get the MIP problem status */    
 if((statmip == XPRB_MIP_SOLUTION) || (statmip == XPRB_MIP_OPTIMAL));
                             /* An integer solution has been found */
 {  
  printf("Objective: %g\n", XPRBgetobjval(bprob)); 
  for(j=0;j<NJ;j++) 
  {                          /* Print the solution for all start times */
   printf("%s: %g\n", XPRBgetvarname(start[j]), XPRBgetsol(start[j])); 
   for(t=0;t<NT-D[j]+1;t++) 
    printf("%s: %g, ", XPRBgetvarname(delta[j][t]), XPRBgetsol(delta[j][t]));
   printf("\n");
  }
 } 
}

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

int main(int argc, char **argv) 
{          
 XPRBprob prob;

 prob=XPRBnewprob("Jobs");       /* Initialization */ 

 cmodel1(prob);                  /* Basic problem definition */
 csolve(prob);                   /* Solve and print solution */

 return 0;     
}

xbqpr12.c
/********************************************************
  BCL Example Problems
  ====================

  file xbqpr12.c
  ``````````````
  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 <stdio.h>
#include "xprb.h"

#define NVar 4

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

int main(int argc, char **argv)
{
 XPRBctr cobj, c;
 XPRBvar x[NVar];
 int i;
 XPRBprob prob;

 prob=XPRBnewprob("QPr12");       /* Initialize a new problem in BCL */

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

/****OBJECTIVE****/
 cobj = XPRBnewctr(prob,"OBJ",XPRB_N);
 XPRBaddterm(cobj, x[0],1); 
		                  /* Define quadratic part of the objective */
 XPRBaddqterm(cobj,x[0],x[0],1);
 XPRBaddqterm(cobj,x[0],x[1],2);
 XPRBaddqterm(cobj,x[1],x[1],2);
 XPRBaddqterm(cobj,x[3],x[3],1);
 XPRBsetobj(prob,cobj);
 
/**** CONSTRAINTS ****/
 c = XPRBnewctr(prob,"C1",XPRB_G);
 XPRBaddterm(c, x[0], 1);
 XPRBaddterm(c, x[1], 2);
 XPRBaddterm(c, x[3], -4);

 c = XPRBnewctr(prob,"C2",XPRB_L);
 XPRBaddterm(c, x[0], 3);
 XPRBaddterm(c, x[2], -2);
 XPRBaddterm(c, x[3], -1);
 XPRBaddterm(c, NULL, 100);
   
 c = XPRBnewctr(prob,"C3",XPRB_L);
 XPRBaddterm(c, x[0], 1);
 XPRBaddterm(c, x[1], 3);
 XPRBaddterm(c, x[2], 3);
 XPRBaddterm(c, x[3], -2);
 XPRBsetrange(c, 10, 30);   

/****SOLVING + OUTPUT****/
 XPRBprintprob(prob);                   /* Print out the problem definition */
 XPRBexportprob(prob,XPRB_MPS,"QPr12"); /* Output the matrix in MPS format */
 XPRBexportprob(prob,XPRB_LP,"QPr12");  /* Output the matrix in LP format */
  
 XPRBsetsense(prob,XPRB_MINIM);         /* Choose the sense of optimization */
 XPRBlpoptimize(prob,"");               /* Solve the QP-problem */

 printf("Objective function value: %g\n", XPRBgetobjval(prob));
 for(i=0;i<NVar;i++)
  printf("%s: %g, ", XPRBgetvarname(x[i]), XPRBgetsol(x[i]));
 printf("\n");
 
 return 0;
}

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

  file xbairport.c
  ````````````````
  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 <stdio.h>
#include "xprb.h"

#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;
 XPRBprob prob;
 XPRBvar x[N],y[N];                     /* x-/y-coordinates to determine */
 XPRBctr cobj, c;

 prob=XPRBnewprob("airport");           /* Initialize a new problem in BCL */

/**** VARIABLES ****/
 for(i=0;i<N;i++) 
  x[i] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("x(%d)",i), -10, 10);
 for(i=0;i<N;i++) 
  y[i] = XPRBnewvar(prob, XPRB_PL, XPRBnewname("y(%d)",i), -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)  */
 cobj = XPRBnewctr(prob, "TotDist", XPRB_N);
  for(i=0;i<N-1;i++)
   for(j=i+1;j<N;j++) 
   {
    XPRBaddqterm(cobj, x[i], x[i], 1);
    XPRBaddqterm(cobj, x[i], x[j], -2);
    XPRBaddqterm(cobj, x[j], x[j], 1);
    XPRBaddqterm(cobj, y[i], y[i], 1);
    XPRBaddqterm(cobj, y[i], y[j], -2);
    XPRBaddqterm(cobj, y[j], y[j], 1);
   } 
 XPRBsetobj(prob, cobj);                /* Set the 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 = XPRBnewctr(prob, XPRBnewname("LimDist_%d",i), XPRB_L);
  XPRBaddqterm(c, x[i], x[i], 1);
  XPRBaddterm(c, x[i], -2*CX[i]);
  XPRBaddterm(c, NULL, -CX[i]*CX[i]);
  XPRBaddqterm(c, y[i], y[i], 1);
  XPRBaddterm(c, y[i], -2*CY[i]);
  XPRBaddterm(c, NULL, -CY[i]*CY[i]);
  XPRBaddterm(c, NULL, R[i]);
 }
 
/****SOLVING + OUTPUT****/
 XPRBsetsense(prob, XPRB_MINIM);        /* Choose the sense of optimization */
 
/* Problem printing and matrix output: */
/*
 XPRBprintprob(prob); 
 XPRBexportprob(prob, XPRB_MPS, "airport");
 XPRBexportprob(prob, XPRB_LP, "airport");
*/

 XPRBlpoptimize(prob,"");               /* Solve the problem */

 printf("Solution: %g\n", XPRBgetobjval(prob));
 for(i=0;i<N;i++)
  printf(" %d: %g, %g\n", i, XPRBgetsol(x[i]), XPRBgetsol(y[i]));

 return 0;
}  

xbcontr1.c
/********************************************************
  BCL Example Problems
  ====================

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

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xprb.h"
#include "xprs.h"

#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;
 XPRBctr c1,c2,cobj;
 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 oprob;
 XPRBprob bprob;

 bprob=XPRBnewprob("Contr1");      /* Initialize a new problem in BCL */

/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = XPRBnewvar(bprob,XPRB_BV,XPRBnewname("x_d%dc%d",d+1,c+1),0,1);
   y[d][c] = 
     XPRBnewvar(bprob,XPRB_SC,XPRBnewname("q_d%dc%d",d+1,c+1),0,OUTPUT[d]);
   XPRBsetlim(y[d][c],5);
  } 

/****OBJECTIVE****/
 cobj = XPRBnewctr(bprob,"OBJ",XPRB_N);  /* Define objective: total cost */
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   XPRBaddterm(cobj,y[d][c],COST[d]);     
 XPRBsetobj(bprob,cobj);                 /* Set objective function */ 
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  c1=XPRBnewctr(bprob,"Size",XPRB_G);  /* Cover the required contract volume */
  c2=XPRBnewctr(bprob,"Min",XPRB_G);   /* At least 2 districts per contract */
  for(d=0;d<District;d++)
  {
   XPRBaddterm(c1,y[d][c],1);
   XPRBaddterm(c2,x[d][c],1);
  }
  XPRBaddterm(c1,NULL,VOLUME[c]);
  XPRBaddterm(c2,NULL,2); 
 } 
 
 for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
 {
  c1=XPRBnewctr(bprob,"Output",XPRB_L);
  for(c=0;c<Contract;c++)
   XPRBaddterm(c1,y[d][c],1);
  XPRBaddterm(c1,NULL,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++)
   XPRBnewprec(bprob,"XY",x[d][c],0,y[d][c]);

/****SOLVING + OUTPUT****/
 XPRBloadmat(bprob);                   /* Load the matrix explicitely */
 oprob = XPRBgetXPRSprob(bprob);       /* Retrieve the Optimizer problem */
 XPRSchgobjsense(oprob, XPRS_OBJ_MINIMIZE);  /* Set sense to minimization */
 XPRSmipoptimize(oprob, "");           /* Solve the MIP problem */

 XPRSgetintattrib(oprob, XPRS_MIPSTATUS, &stat);  /* Get MIP status */
 if((stat==XPRS_MIP_SOLUTION) || (stat==XPRS_MIP_OPTIMAL)) 
                                /* Test whether an integer solution was found */
 {
  XPRSgetdblattrib(oprob, XPRS_MIPOBJVAL, &val);   
  printf("Objective: %g\n", val);
  XPRSgetintattrib(oprob, XPRS_ORIGINALCOLS, &ncol); 
  sol = (double *)malloc(ncol * sizeof(double));
  XPRSgetmipsol(oprob, sol, NULL);     /* Get the primal solution values */
  
  XPRSgetnamelist(oprob, 2, NULL, 0, &len, 0, ncol-1);    
                        /* Get number of bytes required for retrieving names */
  names = (char *)malloc(len*sizeof(char));
  XPRSgetnamelist(oprob, 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)
    printf("%s: %g, ", names+offset, sol[i]);
   offset += strlen(names+offset)+1;
  }     
  printf("\n"); 
  free(names);
  free(sol); 
 }
  
 return 0;
} 


xbcontr2.c
/********************************************************
  BCL Example Problems
  ====================

  file xbcontr2.c
  ```````````````
  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 <stdio.h>
#include <stdlib.h>
#include "xprb.h"
#include "xprs.h"

#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;
 XPRBbegincb(bprob, oprob);

 XPRSgetintattrib(oprob, XPRS_MIPSOLS, &num); /* Get number of the solution */

 XPRBsync(bprob, XPRB_XPRS_SOL);              /* Update BCL solution values */
 printf("Solution %d: Objective value: %g\n", num, XPRBgetobjval(bprob));
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   y = XPRBgetbyname(bprob, XPRBnewname("q_d%dc%d",d+1,c+1), XPRB_VAR);
   if((XPRBgetcolnum(y)>-1) && (XPRBgetsol(y) != 0))
    printf("%s: %g\n", XPRBgetvarname(y), XPRBgetsol(y)); 
  }
  
 XPRBendcb(bprob);
}

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

int main(int argc, char **argv)
{
 int d,c;
 XPRBctr c1,c2,cobj;
 XPRBvar x[District][Contract];    /* Variables indicating whether a project 
                                      is chosen */
 XPRBvar y[District][Contract];    /* Quantities allocated to contractors */
 XPRBprob bprob;
 
 bprob=XPRBnewprob("Contr2");      /* Initialize a new problem in BCL */

/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = XPRBnewvar(bprob,XPRB_BV,XPRBnewname("x_d%dc%d",d+1,c+1),0,1);
   y[d][c] = 
     XPRBnewvar(bprob,XPRB_SC,XPRBnewname("q_d%dc%d",d+1,c+1),0,OUTPUT[d]);
   XPRBsetlim(y[d][c],5);
  } 

/****OBJECTIVE****/
 cobj = XPRBnewctr(bprob,"OBJ",XPRB_N);  /* Define objective: total cost */
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   XPRBaddterm(cobj,y[d][c],COST[d]);     
 XPRBsetobj(bprob,cobj);                 /* Set objective function */ 
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  c1=XPRBnewctr(bprob,"Size",XPRB_G);  /* Cover the required contract volume */
  c2=XPRBnewctr(bprob,"Min",XPRB_G);   /* At least 2 districts per contract */
  for(d=0;d<District;d++)
  {
   XPRBaddterm(c1,y[d][c],1);
   XPRBaddterm(c2,x[d][c],1);
  }
  XPRBaddterm(c1,NULL,VOLUME[c]);
  XPRBaddterm(c2,NULL,2); 
 } 
 
 for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
 {
  c1=XPRBnewctr(bprob,"Output",XPRB_L);
  for(c=0;c<Contract;c++)
   XPRBaddterm(c1,y[d][c],1);
  XPRBaddterm(c1,NULL,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++)
   XPRBnewprec(bprob,"XY",x[d][c],0,y[d][c]);

/****SOLVING + OUTPUT****/
 XPRSsetcbintsol(XPRBgetXPRSprob(bprob), printsolution, bprob);
                                /* Define an integer solution callback */
 XPRBmipoptimize(bprob,"");     /* Solve the MIP problem */
  
 return 0;
} 


xbcontr2s.c
/********************************************************
  BCL Example Problems
  ====================

  file xbcontr2s.c
  ````````````````
  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 <stdio.h>
#include <stdlib.h>
#include "xprb.h"
#include "xprs.h"

#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 */

 XPRBsync(bprob, XPRB_XPRS_SOL);              /* Update BCL solution values */
 printf("Solution %d: Objective value: %g\n", num, XPRBgetobjval(bprob));
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   y = XPRBgetbyname(bprob, XPRBnewname("q_d%dc%d",d+1,c+1), XPRB_VAR);
   if((XPRBgetcolnum(y)>-1) && (XPRBgetsol(y) != 0))
    printf("%s: %g\n", XPRBgetvarname(y), XPRBgetsol(y)); 
  }
}

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

int main(int argc, char **argv)
{
 int d,c;
 XPRBctr c1,c2,cobj;
 XPRBvar x[District][Contract];    /* Variables indicating whether a project 
                                      is chosen */
 XPRBvar y[District][Contract];    /* Quantities allocated to contractors */
 XPRBprob bprob;
 
 bprob=XPRBnewprob("Contr2");      /* Initialize a new problem in BCL */

/**** VARIABLES ****/
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
  {
   x[d][c] = XPRBnewvar(bprob,XPRB_BV,XPRBnewname("x_d%dc%d",d+1,c+1),0,1);
   y[d][c] = 
     XPRBnewvar(bprob,XPRB_SC,XPRBnewname("q_d%dc%d",d+1,c+1),0,OUTPUT[d]);
   XPRBsetlim(y[d][c],5);
  } 

/****OBJECTIVE****/
 cobj = XPRBnewctr(bprob,"OBJ",XPRB_N);  /* Define objective: total cost */
 for(d=0;d<District;d++)
  for(c=0;c<Contract;c++)
   XPRBaddterm(cobj,y[d][c],COST[d]);     
 XPRBsetobj(bprob,cobj);                 /* Set objective function */ 
 
/**** CONSTRAINTS ****/
 for(c=0;c<Contract;c++)
 {
  c1=XPRBnewctr(bprob,"Size",XPRB_G);  /* Cover the required contract volume */
  c2=XPRBnewctr(bprob,"Min",XPRB_G);   /* At least 2 districts per contract */
  for(d=0;d<District;d++)
  {
   XPRBaddterm(c1,y[d][c],1);
   XPRBaddterm(c2,x[d][c],1);
  }
  XPRBaddterm(c1,NULL,VOLUME[c]);
  XPRBaddterm(c2,NULL,2); 
 } 
 
 for(d=0;d<District;d++)        /* Do not exceed max. output of any district */
 {
  c1=XPRBnewctr(bprob,"Output",XPRB_L);
  for(c=0;c<Contract;c++)
   XPRBaddterm(c1,y[d][c],1);
  XPRBaddterm(c1,NULL,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++)
   XPRBnewprec(bprob,"XY",x[d][c],0,y[d][c]);

/****SOLVING + OUTPUT****/
 XPRSsetcbintsol(XPRBgetXPRSprob(bprob), printsolution, bprob);
                                /* Define an integer solution callback */
 XPRSsetintcontrol(XPRBgetXPRSprob(bprob), XPRS_MIPTHREADS, 1);
    /* Desactivate parallel MIP (for synchronization of BCL and Optimizer) */

 XPRBminim(bprob,"g");          /* Solve the MIP problem */
  
 return 0;
}