/*********************************************************************** Xpress Optimizer Examples ========================= file depthfirst.c ````````````````` A DepthFirst Branching Algorithm. Demonstrate the Xpress-MP node callbacks. (c) 2017 Fair Isaac Corporation ***********************************************************************/ #include #include #include "xprs.h" FILE* logFile; typedef struct { int *mStack; int iSize; int iCurrentNode; } nodeStack; void deleteFromStack(XPRSprob prob, nodeStack *stack) { int iNode; XPRSgetintattrib(prob, XPRS_NODES, &iNode); fprintf(logFile, "%d == %d\n", iNode, (*stack).mStack[(*stack).iSize-1]); if( (*stack).mStack[(*stack).iSize-1] == iNode ) (*stack).iSize--; } void XPRS_CC nodeSelection(XPRSprob prob, void *vstack, int *iNode) { nodeStack *stack = (nodeStack*) vstack; XPRSgetintattrib(prob, XPRS_NODES, iNode); fprintf(logFile, "iNode %d --------------------- pop\n", *iNode); if( (*stack).mStack[(*stack).iSize-1] != *iNode ) *iNode = (*stack).mStack[--(*stack).iSize]; fprintf(logFile,"--- Push Node From stack --- Next Node to Branch on is %d ---\n", *iNode); } void XPRS_CC nodeInfeasible(XPRSprob prob, void *stack) { deleteFromStack(prob,stack); fprintf(logFile, "--- Infeasible : Delete Node ---\n"); } void XPRS_CC nodeIntegerFeasible(XPRSprob prob, void *stack) { deleteFromStack(prob,stack); fprintf(logFile,"--- Integer Feasible : Delete Node ---\n"); } void XPRS_CC nodeCutOff(XPRSprob prob, void* stack, int iNode) { deleteFromStack(prob,stack); fprintf(logFile, "--- Cut Off : Delete Node ---\n"); } void XPRS_CC nodeOptimal(XPRSprob prob, void *vstack, int* iFeasible) { int i; /**/ int iNode; nodeStack *stack = (nodeStack*) vstack; XPRSgetintattrib(prob, XPRS_NODES, &iNode); if( !iNode) iNode++; /* push on top of the stack */ (*stack).mStack[((*stack).iSize)++] = iNode; (*stack).iCurrentNode = iNode; fprintf(logFile,"--- Node Optimal : Push Node %d ---\nStack", iNode); /**/ for( i=0; i<(*stack).iSize; i++ ) fprintf(logFile, "%d, ", (*stack).mStack[i]); /**/ fprintf(logFile,"\n"); /**/ } int XPRS_CC nodeStats(XPRSprob prob, void *vstack) { static int iNode = 0; nodeStack *stack = (nodeStack*) vstack; fprintf(logFile, "### This was node: %d ### The Stack has Size %d ###\n", ++iNode, (*stack).iSize); return 0; } int main( int argc, char *argv[] ) { XPRSprob prob; nodeStack stack; int nColumns; int nResult; logFile = fopen("dfb.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); } printf("Start solving problem '%s'. Output to log file 'dfb.log'.\n",argv[1]); XPRSminim(prob, ""); XPRSgetintattrib(prob, XPRS_COLS, &nColumns); XPRSsetintcontrol(prob, XPRS_MIPLOG, 3); XPRSsetintcontrol(prob, XPRS_CUTSTRATEGY, 0); XPRSsetintcontrol(prob, XPRS_NODESELECTION, 2); /* setup node stack */ stack.mStack = (int*) malloc(sizeof(int)*nColumns); stack.iSize = 0; XPRSsetcbchgnode(prob, nodeSelection, &stack); XPRSsetcbinfnode(prob, nodeInfeasible, &stack); XPRSsetcbintsol(prob, nodeIntegerFeasible, &stack); XPRSsetcbnodecutoff(prob, nodeCutOff, &stack); XPRSsetcboptnode(prob, nodeOptimal, &stack); XPRSsetcbgloballog(prob, nodeStats, &stack); XPRSglobal(prob); free(stack.mStack); XPRSfree(); printf("Solving complete.\n"); fclose(logFile); return 0; }