Perform RHS parametrics on a global problem
|
|
Type: | Production planning |
Rating: | 3 (intermediate) |
Description: | We take a production plan model and observe how the optimal value of the objective function changes as we vary the RHS element RESMAX(2), the resources available in Month 2. The program decrements RESMAX(2) from 6 to 1, and for each of these values assesses the feasibility of the revised problem and, where possible, finds the best integer solution. The results are displayed on screen and the problem statistics stored in a log file. |
File(s): | glrhspar.c |
Data file(s): | pplan.mat |
|
glrhspar.c |
/*********************************************************************** Xpress Optimizer Examples ========================= file glrhspar.c ``````````````` Perform RHS parametrics on a global problem. We take a production plan model and observe how the optimal value of the objective function changes as we vary the RHS element RESMAX(2), the resources available in Month 2. The program decrements RESMAX(2) from 6 to 1, and for each of these values assesses the feasibility of the revised problem and, where possible, finds the best integer solution. The results are displayed on screen and the problem statistics stored in a log file. (c) 2017 Fair Isaac Corporation ***********************************************************************/ #include <stdio.h> #include <stdlib.h> #include "xprs.h" /* Optimizer header file */ XPRSprob probg; 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[]="pplan"; /* Problem name */ char sLogFile[]="glrhspar.log"; /* Log file name */ int nRow; /* Number of rows */ int nCol; /* Number of columns */ int nRowIndex[1]; /* Row index of RESMAX(2) */ int *pRowStatus; /* Basis status of the slack, surplus or artificial variable associated with each row */ int *pColStatus; /* Basis status of the columns */ int i; /* Loop counter */ double dResMax2; /* Value of RESMAX(2) */ double dObjValue; /* Objective value of the best integer solution */ int nMatNo; /* Optimizer matrix tag */ int nGlStatus; /* Global status */ int nExpiry; char cOptMessage[200]; char banner[256]; XPRSprob probCopy; /* Delete and define log file */ remove(sLogFile); /* 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); nReturn=XPRScreateprob(&probCopy); if (nReturn != 0 && nReturn != 32) errormsg("XPRScreateprob",__LINE__,nReturn); if (nReturn=XPRSsetlogfile(probg,sLogFile)) errormsg("XPRSsetlogfile",__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); /* Read the problem file */ if (nReturn=XPRSreadprob(probg,sProblem,"")) errormsg("XPRSreadprob",__LINE__,nReturn); /* Set the objective sense */ if (nReturn=XPRSchgobjsense(probg,XPRS_OBJ_MAXIMIZE)) errormsg ("XPRSchgobjsense",__LINE__,nReturn); /* Get the number of rows */ if (nReturn=XPRSgetintattrib(probg,XPRS_ROWS,&nRow)) errormsg("XPRSgetintattrib",__LINE__,nReturn); /* Get the number of columns */ if (nReturn=XPRSgetintattrib(probg,XPRS_COLS,&nCol)) errormsg("XPRSgetintattrib",__LINE__,nReturn); /* Get the row index of RESMAX(2) */ if (nReturn=XPRSgetindex(probg,1,"ResMax02",&nRowIndex[0])) errormsg("XPRSgetindex",__LINE__,nReturn); /* Allocate memory for the basis status arrays */ pRowStatus=malloc(nRow*sizeof(int)); pColStatus=malloc(nCol*sizeof(int)); /* Check for memory shortage */ if (!pRowStatus || !pColStatus) errormsg("malloc",__LINE__,-1); printf("The results of the parameter changes on pplan are:\n\n"); /* Decrement RESMAX(2) from 6 to 1 */ for (i = 6; i>=1; i--) { dResMax2=(double) i; /* Change the RHS */ if (nReturn=XPRSchgrhs(probg,1,nRowIndex,&dResMax2)) errormsg("XPRSchgrhs",__LINE__,nReturn); /* Store the current matrix - as global will later change it */ if (nReturn=XPRScopyprob(probCopy,probg,"temp")) errormsg("XPRScopyprob",__LINE__,nReturn); /* Restore the previous optimal basis - for efficiency */ if (i<6) { if (nReturn=XPRSloadbasis(probCopy,pRowStatus,pColStatus)) errormsg("XPRSloadbasis",__LINE__,nReturn); } /* Solve the root node relaxation */ if (nReturn=XPRSmipoptimize(probCopy,"l")) errormsg("XPRSmipoptimize",__LINE__,nReturn); /* Get the status of the root solve */ if (nReturn=XPRSgetintattrib(probCopy,XPRS_MIPSTATUS,&nGlStatus)) errormsg("XPRSgetintattrib",__LINE__,nReturn); /* If the root node could not be solved to optimality then exit the loop */ if (nGlStatus == XPRS_MIP_LP_NOT_OPTIMAL) { printf(" RESMAX(2)=%2.0f; LP not solved to optimality\n",dResMax2); break; } /* Get the optimal basis */ if (nReturn=XPRSgetbasis(probCopy,pRowStatus,pColStatus)) errormsg("XPRSgetbasis",__LINE__,nReturn); /* Search for an integer solution */ if (nReturn=XPRSmipoptimize(probCopy, "")) errormsg("XPRSmipoptimize",__LINE__,nReturn); /* Check the global status */ if (nReturn=XPRSgetintattrib(probCopy,XPRS_MIPSTATUS,&nGlStatus)) errormsg("XPRSgetintattrib",__LINE__,nReturn); if (nGlStatus == XPRS_MIP_INFEAS) { printf(" RESMAX(2)=%2.0f; infeasible\n",dResMax2); continue; } else if (nGlStatus != XPRS_MIP_OPTIMAL) { printf(" RESMAX(2)=%2.0f; error %i\n",dResMax2, nGlStatus); continue; } /* Get, and then print, the objective value of the best integer solution */ if (nReturn=XPRSgetdblattrib(probCopy,XPRS_MIPOBJVAL,&dObjValue)) errormsg("XPRSgetdblattrib",__LINE__,nReturn); printf(" RESMAX(2)=%2.0f; dObjValue=%4.1f\n",dResMax2,dObjValue); } printf("\n"); /* Free memory, close files */ free(pRowStatus); free(pColStatus); XPRSdestroyprob(probCopy); XPRSdestroyprob(probg); if (nReturn=XPRSfree()) errormsg("XPRSfree",__LINE__,nReturn); 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 */ break; /* Exit and flush buffers */ default: fflush(NULL); break; } } /**************************************************************************************\ * Name: errormsg * * Purpose: Display error information about failed subroutines. * * Arguments: const char *sSubName Subroutine name * * int nLineNo Line number * * int nErrCode Error code * * Return Value: None * \**************************************************************************************/ void errormsg(const char *sSubName,int nLineNo,int nErrCode) { int nErrNo; /* Optimizer error number */ /* Print error message */ printf("The subroutine %s has failed on line %d\n",sSubName,nLineNo); /* Append the error code, if it exists */ if (nErrCode!=-1) printf("with error code %d.\n\n",nErrCode); /* Append Optimizer error number,if available */ if (nErrCode==32) { XPRSgetintattrib(probg,XPRS_ERRORCODE,&nErrNo); printf("The Optimizer error number is: %d.\n\n",nErrNo); } /* Free memory, close files and exit */ XPRSdestroyprob(probg); XPRSfree(); exit(nErrCode); } |
© 2001-2019 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.