/***********************************************************************
Xpress Optimizer Examples
=========================
file mostviolated.c
```````````````````
A Branching rule branching on the most violated Integer/Binary
Demonstrate the Xpress-MP change branch callbacks.
(c) 2017 Fair Isaac Corporation
***********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "xprs.h"
FILE* logFile;
typedef struct {
double* dSolution;
char* cType;
double dTolerance;
int nColumns;
} solutionData;
void XPRS_CC optimizermsg(XPRSprob prob, void* data, const char *sMsg,int nLen,int nMsgLvl);
/* Branch on the most fractional integer */
void XPRS_CC variableSelection(XPRSprob prob, void* vdata, int *iColumn, int* iUp, double* dEstimate )
{
double dDist, dUpDist, dDownDist, dGreatestDist;
int iCol;
solutionData *nodeData = (solutionData*) vdata;
dGreatestDist = 0;
XPRSgetpresolvesol(prob,(*nodeData).dSolution,NULL,NULL,NULL);
for( iCol = 0; iCol < (*nodeData).nColumns; iCol++ )
if( (*nodeData).cType[iCol] == 'I' || (*nodeData).cType[iCol] == 'B' ) {
dUpDist = ceil((*nodeData).dSolution[iCol]) - (*nodeData).dSolution[iCol];
dDownDist = (*nodeData).dSolution[iCol] - floor((*nodeData).dSolution[iCol]);
dDist = (dUpDist>dDownDist)?dUpDist:dDownDist;
if( dDownDist > (*nodeData).dTolerance && dUpDist > (*nodeData).dTolerance )
if( dDist > dGreatestDist ) {
*iColumn = iCol;
dGreatestDist = dDist;
}
}
}
int main( int argc, char *argv[] )
{
XPRSprob prob;
int nResult;
solutionData nodeData;
/* Check number of arguments and tell user to add an input file otherwise. */
if (argc != 2) {
printf("syntax: mostviolated <filename> \n");
return(1);
}
logFile = fopen("mvb.log","w+");
XPRSinit(NULL);
XPRScreateprob(&prob);
nResult = XPRSreadprob(prob, argv[1], "");
if(nResult != 0 && nResult != 32) {
printf("Unable to use problem name from commandline : '%s'\n",argv[1]);
return(0);
}
/* Tell Optimizer to call optimizermsg whenever a message is output */
XPRSsetcbmessage(prob,optimizermsg,NULL);
printf("Start solving problem '%s'.\n",argv[1]);
XPRSmipoptimize(prob,"l");
XPRSsetintcontrol(prob,XPRS_MIPLOG,3);
XPRSsetintcontrol(prob,XPRS_CUTSTRATEGY,0);
/* setup data */
XPRSgetintattrib(prob,XPRS_COLS,&(nodeData.nColumns));
XPRSgetdblcontrol(prob,XPRS_MATRIXTOL,&(nodeData.dTolerance));
nodeData.dSolution = (double*) malloc(sizeof(double)*nodeData.nColumns);
nodeData.cType = (char*) malloc(sizeof(char)*nodeData.nColumns);
XPRSgetcoltype(prob,nodeData.cType,0,nodeData.nColumns-1);
XPRSsetcbchgbranch(prob,variableSelection,&nodeData);
XPRSmipoptimize(prob,"");
free(nodeData.dSolution);
free(nodeData.cType);
XPRSfree();
printf("Solving complete.\n");
fclose(logFile);
return 0;
}
/**********************************************************************************\
* Name: optimizermsg *
* Purpose: Display Optimizer error messages and warnings. *
* Arguments: const char *sMsg Message string *
* int nLen Message length *
* int nMsgLvl Message type *
* Return Value: None *
\**********************************************************************************/
void XPRS_CC optimizermsg(XPRSprob prob, void* data, const char *sMsg,int nLen,int nMsgLvl)
{
switch (nMsgLvl) {
/* Print Optimizer error messages and warnings */
case 4: /* error */
case 3: /* warning */
printf("%*s\n",nLen,sMsg);
break;
/* Ignore other messages */
case 2: /* dialogue */
case 1: /* information */
printf("%*s\n",nLen,sMsg);
break;
/* Exit and flush buffers */
default:
fflush(NULL);
break;
}
}
|