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