| 1454 | } |
| 1455 | |
| 1456 | HPresolve::Result HPresolve::prepareProbing( |
| 1457 | HighsPostsolveStack& postsolve_stack, bool& firstCall) { |
| 1458 | HighsDomain& domain = mipsolver->mipdata_->getDomain(); |
| 1459 | HighsCliqueTable& cliquetable = mipsolver->mipdata_->cliquetable; |
| 1460 | |
| 1461 | shrinkProblem(postsolve_stack); |
| 1462 | |
| 1463 | toCSC(model->a_matrix_.value_, model->a_matrix_.index_, |
| 1464 | model->a_matrix_.start_); |
| 1465 | okFromCSC(model->a_matrix_.value_, model->a_matrix_.index_, |
| 1466 | model->a_matrix_.start_); |
| 1467 | |
| 1468 | cliquetable.setMaxEntries(numNonzeros()); |
| 1469 | |
| 1470 | // first tighten all bounds if they have an implied bound that is tighter |
| 1471 | // than their column bound before probing this is not done for continuous |
| 1472 | // columns since it may allow stronger dual presolve and more aggregations |
| 1473 | double hugeBound = primal_feastol / kHighsTiny; |
| 1474 | for (HighsInt i = 0; i != model->num_col_; ++i) { |
| 1475 | if (std::abs(implColLower[i]) <= hugeBound && |
| 1476 | implColLower[i] > model->col_lower_[i]) |
| 1477 | HPRESOLVE_CHECKED_CALL(changeColLower(i, implColLower[i])); |
| 1478 | |
| 1479 | if (std::abs(implColUpper[i]) <= hugeBound && |
| 1480 | implColUpper[i] < model->col_upper_[i]) |
| 1481 | HPRESOLVE_CHECKED_CALL(changeColUpper(i, implColUpper[i])); |
| 1482 | } |
| 1483 | |
| 1484 | // prepare for domain propagation |
| 1485 | mipsolver->mipdata_->setupDomainPropagation(); |
| 1486 | |
| 1487 | // first call? |
| 1488 | firstCall = !mipsolver->mipdata_->cliquesExtracted; |
| 1489 | |
| 1490 | domain.propagate(); |
| 1491 | if (domain.infeasible()) return Result::kPrimalInfeasible; |
| 1492 | |
| 1493 | // extract cliques that are part of the formulation every time before probing |
| 1494 | // after the first call we only add cliques that directly correspond to set |
| 1495 | // packing constraints so that the clique merging step can extend/delete them |
| 1496 | if (firstCall) { |
| 1497 | mipsolver->mipdata_->cliquesExtracted = true; |
| 1498 | |
| 1499 | cliquetable.extractCliques(*mipsolver); |
| 1500 | if (domain.infeasible()) return Result::kPrimalInfeasible; |
| 1501 | |
| 1502 | // during presolve we keep the objective upper bound without the current |
| 1503 | // offset so we need to update it |
| 1504 | |
| 1505 | if (mipsolver->mipdata_->upper_limit != kHighsInf) { |
| 1506 | double tmpLimit = mipsolver->mipdata_->upper_limit; |
| 1507 | mipsolver->mipdata_->upper_limit = tmpLimit - model->offset_; |
| 1508 | cliquetable.extractObjCliques(*mipsolver); |
| 1509 | mipsolver->mipdata_->upper_limit = tmpLimit; |
| 1510 | if (domain.infeasible()) return Result::kPrimalInfeasible; |
| 1511 | } |
| 1512 | |
| 1513 | domain.propagate(); |
nothing calls this directly
no test coverage detected