coin-or / Clp.old

This a mirror of the subversion repository on COIN-OR.
https://projects.coin-or.org/Clp
Other
36 stars 20 forks source link

[TRAC] ClpSolve::infeasibleReturn ignored #20

Closed qtothec closed 6 years ago

qtothec commented 6 years ago

Moved from TRAC as part of COIN fORgery: https://projects.coin-or.org/Clp/ticket/55

It seems that the ClpSolve::infeasibleReturn option is ignored when infeasibility is detected from tightening primal bounds. See the code below from trunk (ClpSolve?.cpp starting at line 915):

if (method == ClpSolve::useDual) {
          double * saveLower = NULL;
          double * saveUpper = NULL;
          if (presolve == ClpSolve::presolveOn) {
               int numberInfeasibilities = model2->tightenPrimalBounds(0.0, 0);
               if (numberInfeasibilities) {
                    handler_->message(CLP_INFEASIBLE, messages_)
                              << CoinMessageEol;
                    delete model2;
                    model2 = this;
                    presolve = ClpSolve::presolveOff;
               }
          } else if (numberRows_ + numberColumns_ > 5000) {
               // do anyway
               saveLower = new double[numberRows_+numberColumns_];
               CoinMemcpyN(model2->columnLower(), numberColumns_, saveLower);
               CoinMemcpyN(model2->rowLower(), numberRows_, saveLower + numberColumns_);
               saveUpper = new double[numberRows_+numberColumns_];
               CoinMemcpyN(model2->columnUpper(), numberColumns_, saveUpper);
               CoinMemcpyN(model2->rowUpper(), numberRows_, saveUpper + numberColumns_);
               int numberInfeasibilities = model2->tightenPrimalBounds();
               if (numberInfeasibilities) {
                    handler_->message(CLP_INFEASIBLE, messages_)
                              << CoinMessageEol;
                    CoinMemcpyN(saveLower, numberColumns_, model2->columnLower());
                    CoinMemcpyN(saveLower + numberColumns_, numberRows_, model2->rowLower());
                    delete [] saveLower;
                    saveLower = NULL;
                    CoinMemcpyN(saveUpper, numberColumns_, model2->columnUpper());
                    CoinMemcpyN(saveUpper + numberColumns_, numberRows_, model2->rowUpper());
                    delete [] saveUpper;
                    saveUpper = NULL;
               }
          }

At an earlier point in the same file (line 502), there is:

if (!model2) {
               handler_->message(CLP_INFEASIBLE, messages_)
                         << CoinMessageEol;
               model2 = this;
           eventHandler()->event(ClpEventHandler::presolveInfeasible);
               problemStatus_ = pinfo->presolveStatus(); 
               if (options.infeasibleReturn() || (moreSpecialOptions_ & 1) != 0) {
         delete pinfo;
                    return -1;
               }
               presolve = ClpSolve::presolveOff;
      }

The code in the first snippet should include a check for options.infeasibleReturn() as in the second snippet.

jjhforrest commented 6 years ago

Seems already fixed