Forum Discussion

FICO's avatar
FICO
Community Manager
4 years ago

How to upgrade method XPRSprob.Range?

Hello,

I am trying to migrate XPress interface from 8.4.2 to 8.14 version. I found that methods below in XPRSprob class were removed.

XPRSprob.Range()

XPRSprob.GetColRange(...)

XPRSprob.GetRowRange(...)

Can someone help me with this issue? Thanks.

6 Replies

  • FICO's avatar
    FICO
    Community Manager

    These functions were removed in version 8.12. Sensitivy information can now be obtained using functions XPRSprob.Bndsa() and XPRSprob.RHSsa().

    Please also see the slightly more detailed documentation for the respective C API functions here and here.

  • FICO's avatar
    FICO
    Community Manager

    int XPRS_CC XPRSgetcolrange(XPRSprob prob, double upact[], double loact[], double uup[], double udn[], double ucost[], double lcost[]);

    int XPRS_CC XPRSgetrowrange(XPRSprob prob, double upact[], double loact[], double uup[], double udn[]);

    I check the functions but don't understand the relationships.

    i.e. Ho to map variable upact[] tp new API?

  • FICO's avatar
    FICO
    Community Manager

    Here is a small (untested) C code that implements the old functions using the new ones. I hope it is easy to convert this to .NET or deduce how to map arguments.

    Please come back if it is not.

    /* Note that pointer arguments must be pairwise non-NULL, for example,
     * if upact is NULL then loact must be NULL as well.
     */
    int XPRSgetcolrange(
      XPRSprob prob,
      double *upact,  //!< upper limit of the bound the variable is non-basic on before a basis change occurs; sol value otherwise
      double *loact,  //!< lower limit of the bound the variable is non-basic on before a basis change occurs; sol value otherwise
      double *unup,   //!< objective change per unit increase of variable - reduced cost
      double *undn,   //!< objective change per unit decrease of variable - negated reduced cost
      double *ucost,  //!< upper limit of objective coefficient before a before a basis change occurs
      double *lcost   //!< lower limit of objective coefficient before a before a basis change occurs
      ) {
      int result = 0;
      double *x = NULL;
      double *dj = NULL;
      int j;
      int *ind = NULL;
      int *colstat = NULL;
      int cols;
     
      /* Note: we don't check preconditions like "optimal sol available",
       *       "not MIP presolved", ... here.
       */
     
      if ( (result = XPRSgetintattrib(prob, XPRS_COLS, &cols)) != 0 )
        goto exit_cleanup;
     
      if ( !(x = malloc(sizeof(*x) * cols)) ||
           !(dj = malloc(sizeof(*dj) * cols)) ||
           !(ind = malloc(sizeof(*ind) * cols)) ||
           !(colstat = malloc(sizeof(*colstat) * cols)))
      {
        /* Out of memory. */
        result = -1;
        goto exit_cleanup;
      }
     
      if ( (result = XPRSgetlpsol(prob, x, NULL, NULL, dj)) != 0 ||
           (result = XPRSgetbasis(prob, NULL, colstat)) != 0 )
        goto exit_cleanup;
     
     
      // bounds
      if (upact && loact) {
        for (j = 0; j < cols; ++j) {
          switch (colstat[j]) {
          case 2: // At upper bound
            if ( (result = XPRSbndsa(prob, 1, &j, NULL, NULL, &loact[j], &upact[j])) != 0 )
              goto exit_cleanup;
            break;
          case 1: // Basic
            loact[j] = x[j];
            upact[j] = x[j];
            break;
          case 3: // Superbasic
            loact[j] = x[j];
            upact[j] = x[j];
            break;
          case 0: // At lower bound
            if ( (result = XPRSbndsa(prob, 1, &j, &loact[j], &upact[j], NULL, NULL)) != 0 )
              goto exit_cleanup;
            break;
          }
        }
      }
      // reduced costs
      if (unup && undn) {
        for (j = 0; j < cols; ++j) {
          unup[j] = dj[j];
          undn[j] = -dj[j];
        }
      }
      // Objective sensitivty
      if (ucost && lcost) {
        // Build list of all indices
        for (j = 0; j < cols; ++j) {
          ind[j] = j;
        }
        if ( (result = XPRSobjsa(prob, cols, ind, lcost, ucost)) != 0 )
          goto exit_cleanup;
      }
     
     exit_cleanup:
     
      free(colstat);
      free(ind);
      free(dj);
      free(x);
      
      return result;
    }
     
    /* Note that pointer arguments must be pairwise non-NULL, for example,
     * if upact is NULL then loact must be NULL as well.
     */
    int XPRSgetrowrange(
      XPRSprob prob,
      double *upact, //!< upper bound of the RHS value before a basis change occurs
      double *loact, //!< lower bound of the RHS value before a basis change occurs
      double *unup,  //!< objective change per unit increase of RHS - dual multiplier
      double *undn   //!< objective change per unit decrease of RHS - minus dual multiplier
    ) {
      int result = 0;
      double *dual = NULL;
      int i, rows;
      int *ind = NULL;
     
      /* Note: we don't check preconditions like "optimal sol available",
       *       "not MIP presolved", ... here.
       */
     
      if ( (result = XPRSgetintattrib(prob, XPRS_ROWS, &rows)) != 0 )
        goto exit_cleanup;
     
      if ( !(dual = malloc(sizeof(*dual) * rows)) ||
           !(ind = malloc(sizeof(*ind) * rows)) )
      {
        /* Out of memory. */
        result = -1;
        goto exit_cleanup;
      }
     
      if ( (result = XPRSgetlpsol(prob, NULL, NULL, dual, NULL)) != 0 )
        goto exit_cleanup;
     
      // duals
      if (unup && undn) {
        for (i = 0; i < rows; ++i) {
          unup[i] = dual[i];
          undn[i] = -dual[i];
        }
      }
     
      // RHS sensitivty
      if (upact && loact) {
        // Build list of all indices
        for (i = 0; i < rows; ++i) {
          ind[i] = i;
        }
        if ( (result = XPRSrhssa(prob, rows, ind, loact, upact)) != 0 )
          goto exit_cleanup;
      }
     
     exit_cleanup:
      free(ind);
      free(dual);
     
      return result;
    }
  • FICO's avatar
    FICO
    Community Manager

    This issue seems to be resolved. Thanks.

    Another issue we saw is that model.Run() is much slower than before. Compared with 8.14, it takes 3s now, but<1s in 8.14.

    Any comments for this? Thanks.

    ' compile/load/run model

    model = mosel.CompileAndLoad("g", "problem.mos")

    model.Run()

  • FICO's avatar
    FICO
    Community Manager

    This is an unrelated question, can you please start a new topic for it? It would also be good if you could at the respective solver logs (pre 8.14 and 8.14) to your post.

    Even better if you could add the "problem.mos" to your post so that others can try to reproduce the problem.

  • FICO's avatar
    FICO
    Community Manager

    Thanks. I'll submit a new question if needed.