Initializing help system before first use

Apply an integer fixing heuristic to a MIP problem


Type: Power generation
Rating: 3
Description:

We take the power generation problem stored in hpw15.mat which seeks to optimise the operating pattern of a group of electricity generators. We solve this MIP with a very loose integer tolerance and then fix all binary and integer variables to their rounded integer values, changing both their lower and upper bounds. We then solve the resulting LP.

The results are displayed on screen and the problem statistics stored in a logfile.

File(s): roundint.c
Data file(s): hpw15.mat


roundint.c
/***********************************************************************
   Xpress Optimizer Examples
   =========================

   file roundint.c
   ```````````````
   Apply an integer fixing heuristic to a MIP problem. The program  
   also demonstrates the use of the integer solution callback.

   Description: We take the power generation problem stored in hpw15.mat which 
   seeks to optimise the operating pattern of a group of electricity  
   generators. We solve this MIP with a very loose integer tolerance 
   and then fix all binary and integer variables to their rounded 
   integer values, changing both their lower and upper bounds. We then
   solve the resulting LP. 
   The results are displayed on screen and the problem statistics 
   stored in a logfile.

   (c) 2017 Fair Isaac Corporation       
***********************************************************************/


#include 
#include 
#include "xprs.h"                      /* Optimizer header file */

XPRSprob probg;

#define TOL 0.3                        /* Integer tolerance */

void XPRS_CC intsol(XPRSprob, void* data);
void XPRS_CC optimizermsg(XPRSprob prob, void* data, const char *sMsg,int nLen,int nMsgLvl);
void errormsg(const char *sSubName,int nLineNo,int nErrCode);


int main()
{
   int nReturn;                        /* Return value of Optimizer subroutine */
   int nOptimizerVersion;              /* Optimizer version number */
   char sProblem[]="..\\data\\hpw15";  /* Problem name */
   char sLogFile[]="roundint.log";     /* Log file name */
   int nExpiry;

   int nCol;                           /* Number of columns */

   /* Global problem information */
   int nGlEnt;                         /* Number of global entities: binary, integer,
                                          semi-continuous and partial integer variables */
   int nSet;                           /* Number of S1 and S2 sets */
   int *pGlInd;                        /* Column indices of the global entities */
   char *pGlType;                      /* Global entity types

   /* Bound changes */
   int *pBndInd;                       /* Column indices of the bounds to be changed */
   char *pBndType;                     /* New bound types - always 'B', since both the upper
                                          and lower bounds are to be changed */
   double *pBndVal;                    /* New bound values */
   int nBnd;                           /* Bound counter */
   int i;                              /* Loop counter */
   int j;                              /* Holder for the bound indices */

   /* Solution information */
   double *x,*y;                       /* MIP and LP solution values */
   double dObjVal;                     /* Objective function value */

   char banner[256];


   /* Initialise Optimizer */

   nReturn=XPRSinit(NULL);
   XPRSgetbanner(banner); printf("%s",banner);
   if (nReturn == 8) return(1);

   nReturn=XPRScreateprob(&probg);
   if (nReturn != 0 && nReturn != 32) errormsg("XPRScreateprob",__LINE__,nReturn);

   /* Tell Optimizer to call optimizermsg whenever a message is output */
   nReturn=XPRSsetcbmessage(probg,optimizermsg,NULL);

   /* Get and display the Optimizer version number */
   if (nReturn=XPRSgetintcontrol(probg,XPRS_VERSION,&nOptimizerVersion))
   		errormsg("XPRSgetintcontrol",__LINE__,nReturn);
   printf("Xpress Optimiser Subroutine Library Release %.2f\n\n",
      (float)nOptimizerVersion/100);

   /* Disable cuts - or the optimal solution will be found at the top node
      and the integer solution callback will hardly be used */
   if (nReturn=XPRSsetintcontrol(probg,XPRS_CUTSTRATEGY,0))
   	   errormsg("XPRSsetintcontrol",__LINE__,nReturn);

   /* Read the problem file */
   if (nReturn=XPRSreadprob(probg,sProblem,"")) errormsg("XPRSreadprob",__LINE__,nReturn);

   /*** Solve MIP with loose integer tolerance ***/

   /* Set integer feasibility tolerance */
   if (nReturn=XPRSsetdblcontrol(probg,XPRS_MIPTOL,TOL)) errormsg("XPRSsetdblcontrol",__LINE__,nReturn);

   /* Tell Optimizer to print out global information at each node and call intsol
      whenever an integer solution is found */
   if (nReturn=XPRSsetintcontrol(probg,XPRS_MIPLOG,3)) errormsg("XPRSsetintcontrol",__LINE__,nReturn);
   nReturn=XPRSsetcbintsol(probg,&intsol,NULL);

   /* Get the number of columns */
   if (nReturn=XPRSgetintattrib(probg,XPRS_COLS,&nCol)) errormsg("XPRSgetintattrib",__LINE__,nReturn);

   /* Allocate memory for MIP solution array and check for memory shortage */
   x=malloc(nCol * sizeof(double));
   if (!x) errormsg("malloc",__LINE__,-1);

   /* Solve the MIP problem and get the solution values */
   printf("Applying an integer fixing heuristic to problem %s:-\n\n",sProblem);
   printf("Solving MIP with global:\n\n");
   if (nReturn=XPRSminim(probg,"g")) errormsg("XPRSminim",__LINE__,nReturn) ;
   if (nReturn=XPRSgetsol(probg,x,NULL,NULL,NULL)) errormsg("XPRSgetsol",__LINE__,nReturn);

   /*** Round off the values of all binary and integer variables  ***/

   /* Allocate memory for global entity arrays */
   pGlInd=malloc(nCol * sizeof(int));
   pGlType=malloc(nCol * sizeof(char));
   if (!pGlInd || !pGlType) errormsg("malloc",__LINE__,-1);

   /* Retrieve global entity information */
   if (nReturn=XPRSgetglobal(probg,&nGlEnt,&nSet,pGlType,pGlInd,NULL,NULL,NULL,NULL,NULL))
       errormsg("XPRSgetglobal",__LINE__,nReturn);

   /* Allocate memory for bound arrays */
   pBndInd=malloc(nGlEnt * sizeof(int));
   pBndVal=malloc(nGlEnt * sizeof(double));
   pBndType=malloc(nGlEnt * sizeof(char));
   if (!pBndInd || !pBndVal || !pBndType) errormsg("malloc",__LINE__,-1);

   /* Initialise bound counter */
   nBnd = 0;

   /* Go through global entities */
   for(i=0; i