/*********************************************************************** 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 #include #include #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 \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; } }