Forum Discussion

FICO's avatar
FICO
Community Manager
1 year ago

How to detect between termination by timeout or tolerance

The documentation doesn't clearly explain XPRS_UNF. I believe it means the optimisation finished either due to a XPRS_MAXTIME being reached or a tolerance being met. Without comparing time and tolerances achieved vs the input limits, is there a way to see which criteria caused an optimisation to finish? This is important to me as a timeout needs to be flagged clearly to users as a potentially poor solution to an optimisation, whereas a tolerance is a termination within approved limits.

6 Replies

  • FICO's avatar
    FICO
    Community Manager

    You can query the solver attribute STOPSTATUS. Assuming you are working with Mosel, you could use for example:

     declarations
       STOPVAL: array(integer) of string
     end-declarations
     STOPVAL::([XPRS_STOP_NONE, XPRS_STOP_TIMELIMIT, XPRS_STOP_CTRLC,
       XPRS_STOP_NODELIMIT, XPRS_STOP_ITERLIMIT, XPRS_STOP_MIPGAP,
       XPRS_STOP_SOLLIMIT, XPRS_STOP_MEMORYERROR, XPRS_STOP_USER,	
       XPRS_STOP_SOLVECOMPLETE, XPRS_STOP_LICENSELOST, XPRS_STOP_NUMERICALERROR])
       ["solve completed normally", "time limit hit", "user hit control C", 
       "node limit hit", "LP iteration limit hit", "MIP gap is sufficiently small",
       "solution limit hit", "insufficient memory", "user interrupt", 
       "MIP solve completed without fully exploring the tree", 
       "license has been lost", "numerical errors encountered"]
     
     if getprobstat=XPRS_UNF:
      writeln(STOPVAL(getparam("XPRS_STOPSTATUS")))
     
  • FICO's avatar
    FICO
    Community Manager

    Thanks for such a quick response Susanne!

  • FICO's avatar
    FICO
    Community Manager

    Hi. Can you please explain what how XPRS_STOP_SOLVECOMPLETE differs from the other Stopping Conditions?

  • FICO's avatar
    FICO
    Community Manager

    Hi Colin.

    Most of the stopping criteria state that a user-imposed working limit has been hit: TIMELIMIT, SOLLIMIT, NODELIMIT, ITERLIMIT, MIPGAP

    for limits on the execution time, the maximum number of solutions to be found, the maximum number of nodes in the search tree to be explored, the maximum number of simplex iterations to be conducted, and the limit for the primal-dual gap before the optimization can be stopped, respectively.

    The next common thing are errors like MEMORYERROR, NUMERICALERROR, and LICENSELOST.

     You are right that SOLVECOMPLETE is a bit of a special case: It indicates that the problem could be solved to proven optimality, without needing to explore the full search tree, typically by the solver detecting some globally valid information that proves that no improving solution can be found anymore.

     As two examples, consider: 

     a) When the MIP problem decomposes into a set of completely(!) independent subproblems, Xpress will solve each of them individually. If one of those subproblems is found to be infeasible, then the overall problem is infeasible. This can be concluded without finishing the other problems (or even attempting to do so).

     b) The solver will generate new valid constraints throughout the search, so-called cutting planes. If one such globally valid(!) constraint can be reduced to a false statement such as 1 <= 0, this mathematically proves that the remaining search problem is empty and the current incumbent solution is optimal.

  • FICO's avatar
    FICO
    Community Manager

    Hi Timo.

    Thanks for your answer. Based on this I have implemented handling of this code using the constant XPRS_STOP_SOLVECOMPLETE.

    I have found that the compiler flags this as an unknown constant in XPRESS 9.1 and so I will need to implement the constant's integer value instead.

    A small complaint I have about XPRESS is that the numerical values of constants don't appear to be documented anywhere apart from the subset that can be looked up in XPRS.BAS.

    Colin

  • FICO's avatar
    FICO
    Community Manager

    With Mosel, you can use the Mosel command-line command 'exam[ine]' to list constants with their values, for example the listing for the module mmxprs is obtained via:

    mosel exam -c mmxprs