FICO
FICO Xpress Optimization Examples Repository
FICO Optimization Community FICO Xpress Optimization Home
Back to examples browserPrevious exampleNext example

Perform RHS parametrics on a global problem

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.



Source Files

Data Files





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[]="..\\data\\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 nLPStatus;                     /* LP status - feasible or infeasible */
   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);

   /* 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 LP problem */
      if (nReturn=XPRSmaxim(probCopy,"")) errormsg("XPRSmaxim",__LINE__,nReturn);

      /* Get the LP status */
      if (nReturn=XPRSgetintattrib(probCopy,XPRS_LPSTATUS,&nLPStatus))
      	 errormsg("XPRSgetintattrib",__LINE__,nReturn);

      /* If the problem is infeasible then exit the loop */
      if (nLPStatus == 2) {
         printf("   RESMAX(2)=%2.0f;  problem now infeasible\n",dResMax2);
         break;
      }

      /* Get the optimal basis */
      if (nReturn=XPRSgetbasis(probCopy,pRowStatus,pColStatus)) errormsg("XPRSgetbasis",__LINE__,nReturn);

      /* Search for an integer solution */
      if (nReturn=XPRSglobal(probCopy)) errormsg("XPRSglobal",__LINE__,nReturn);

      /* 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);
}




Back to examples browserPrevious exampleNext example