Initializing help system before first use

10 best solutions with the MIP solution enumerator


Type: Power generation
Rating: 3 (intermediate)
Description: We take the power generation problem stored in hpw15.mat which seeks to optimise the operating pattern of a group of electricity generators. We run the MIP solution enumerator on the problem using the default setup obtaining the best 10 solutions. The best 10 solutions are stored to a MIP solution pool. The solutions' objectives and solution values are printed to screen.
File(s): mipsolenum.c
Data file(s): hpw15.mat


mipsolenum.c
/***********************************************************************
   Xpress Optimizer Examples
   =========================

   file mipsolenum.c
   `````````````````
   Find the 10 best solutions with the MIP solution enumerator 

   We take the power generation problem stored in hpw15.mat which seeks to 
   optimise the operating pattern of a group of electricity generators. We 
   run the MIP solution enumerator on the problem using the default setup  
   obtaining the best 10 solutions. The best 10 solutions are stored to a  
    MIP solution pool.  The solutions' objectives and solution values are  
   printed to screen.

   (c) 2017 Fair Isaac Corporation       
***********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "xprs.h"                     /* Optimizer header file */
#include "xprs_mse_defaulthandler.h"  /* 'Default' enumerated mip solution handler */

void errormsg(const char *sSubName,int nLineNo,int nErrCode);


void main(void) {
  int nReturn;
  XPRSprob prob;
  XPRSmipsolpool msp;
  XPRSmipsolenum mse;
  int nMaxSols, iPresolveOps, iMIPPresolve;
  int i, j, nSols, nCols, iSolutionId, iSolutionIdStatus;
  double dObj, dSol;
  const char *sProblem = "../data/hpw15";

  nReturn = XPRSinit("");
  if (nReturn!=0 && nReturn!=16) {
    char errmsgbuf[2048];
    XPRSgetlicerrmsg(errmsgbuf,2048);
    printf("We were unable to license the Xpress-optimizer: %s\n", errmsgbuf);
    exit(nReturn);
  }


  nReturn = XPRS_mse_create(&mse);
  if (nReturn != 0) errormsg("XPRS_mse_create",__LINE__,nReturn);

  nReturn = XPRScreateprob(&prob);
  if (nReturn != 0) errormsg("XPRScreateprob",__LINE__,nReturn);

  nReturn = XPRS_msp_create(&msp);
  if (nReturn != 0) errormsg("XPRS_msp_create",__LINE__,nReturn);

  nReturn = XPRSreadprob(prob, sProblem, "");
  if (nReturn != 0) errormsg("XPRSreadprob",__LINE__,nReturn);

  nReturn = XPRSgetintattrib(prob, XPRS_COLS, &nCols);
  if (nReturn != 0) errormsg("XPRSgetintattrib",__LINE__,nReturn);

  /* Disable heuristics to avoid duplicate solutions being stored */
  nReturn = XPRSsetintcontrol(prob, XPRS_HEURSTRATEGY, 0);
  if (nReturn != 0) errormsg("XPRSsetintcontrol",__LINE__,nReturn);

  XPRSgetintcontrol(prob, XPRS_PRESOLVEOPS, &iPresolveOps);  
  iPresolveOps &= ~(1 << 3); /* Disable dual reduction operations */
  iPresolveOps &= ~(1 << 5); /* Disable duplicate column removal  */
  XPRSsetintcontrol(prob, XPRS_PRESOLVEOPS, iPresolveOps);  

  XPRSgetintcontrol(prob, XPRS_MIPPRESOLVE, &iMIPPresolve);  
  iMIPPresolve &= ~(1 << 4); /* Disable MIP dual reduction operations */
  XPRSsetintcontrol(prob, XPRS_MIPPRESOLVE, iMIPPresolve);  

  /* Run the enumeration */
  nMaxSols = 10;
  nReturn = XPRS_mse_minim(mse, prob, msp, XPRS_mse_defaulthandler, NULL, &nMaxSols);
  if (nReturn != 0) errormsg("XPRS_mse_minim",__LINE__,nReturn);

  /* Print out the solutions found */
  nReturn = XPRS_mse_getintattrib(mse, XPRS_MSE_SOLUTIONS, &nSols);
  if (nReturn != 0) errormsg("XPRS_mse_getintattrib",__LINE__,nReturn);
  for(i = 1; i <= nSols; i++) {
    nReturn = XPRS_mse_getsollist(mse, XPRS_MSE_METRIC_MIPOBJECT, i, i, &iSolutionId, NULL, NULL);
    if (nReturn!=0) errormsg("XPRS_mse_getsollist",__LINE__,nReturn);
    nReturn = XPRS_mse_getsolmetric(mse, iSolutionId, &iSolutionIdStatus, XPRS_MSE_METRIC_MIPOBJECT, &dObj);
    if (nReturn!=0) errormsg("XPRS_mse_getsolmetric",__LINE__,nReturn);
    printf("--------\n%3i = %12.5f\n", i, dObj);

    for(j = 0; j < nCols; j++) {
      nReturn = XPRS_msp_getsol(msp, iSolutionId, &iSolutionIdStatus, &dSol, j, j, NULL);
      if (nReturn!=0) errormsg("XPRS_msp_getsol",__LINE__,nReturn);
      printf("%3i = %12.5f\n", j, dSol);
    }
  }

  XPRS_msp_destroy(msp);
  XPRSdestroyprob(prob);
  XPRS_mse_destroy(mse);
  XPRSfree();
}


/**********************************************************************************\
* 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",nErrCode);

   /* Free memory, close files and exit */
   XPRSfree();
   exit(nErrCode);
}