FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Contract - Semi-continuous variables, predefined constraint functions, combine BCL with Xpress Optimizer

Description
A small MIP-problem example demonstrating how to define semi-continuous variables, use predefined constraint functions and retrieve the problem status.

Two modified versions (documented in the 'BCL Reference Manual') show how to (1) combine BCL problem input with problem solving in Xpress Optimizer and (2) use an Xpress Optimizer solution callback with a BCL model.

Further explanation of this example: 'BCL Reference Manual', Appendix B Using BCL with the Optimizer library

xbcontrcpp.zip[download all files]

Source Files





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

Back to examples browserPrevious exampleNext example