MCPcopy Create free account
hub / github.com/ERGO-Code/HiGHS / updateColImpliedBounds

Method updateColImpliedBounds

highs/presolve/HPresolve.cpp:669–742  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

667}
668
669HPresolve::Result HPresolve::updateColImpliedBounds(HighsInt row, HighsInt col,
670 double val) {
671 // propagate implied column bound upper bound if row has an upper bound
672 double rowLower, rowUpper;
673 if (!checkUpdateColImpliedBounds(row, &rowLower, &rowUpper))
674 return Result::kOk;
675
676 const double threshold = 1000 * primal_feastol;
677
678 auto checkImpliedBound = [&](HighsInt row, HighsInt col, double val,
679 double rowBnd, double residualAct,
680 HighsInt direction) {
681 if (direction * residualAct <= -kHighsInf) return Result::kOk;
682 double impliedBound = static_cast<double>(
683 (static_cast<HighsCDouble>(rowBnd) - residualAct) / val);
684
685 if (std::abs(impliedBound) * kHighsTiny > primal_feastol)
686 return Result::kOk;
687
688 // do not use the implied bound if this a not a model row, since the
689 // row can be removed and should not be used, e.g., to identify a
690 // column as implied free
691 bool useImplBound = mipsolver == nullptr ||
692 mipsolver->mipdata_->postSolveStack.getOrigRowIndex(
693 row) < mipsolver->orig_model_->num_row_;
694
695 if (direction * val > 0) {
696 // upper bound
697 // when solving a MIP, keep (1) tighter bounds on integer variables or (2)
698 // implied bound (as column bound)
699 bool updateColBound =
700 mipsolver != nullptr &&
701 ((model->integrality_[col] != HighsVarType::kContinuous &&
702 impliedBound < model->col_upper_[col] - primal_feastol) ||
703 (!useImplBound &&
704 impliedBound < model->col_upper_[col] - threshold));
705
706 // only tighten bound if it is tighter by a wide enough margin
707 if (useImplBound && impliedBound < implColUpper[col] - threshold)
708 changeImplColUpper(col, impliedBound, row);
709 if (updateColBound)
710 HPRESOLVE_CHECKED_CALL(changeColUpper(col, impliedBound));
711 } else {
712 // lower bound
713 // when solving a MIP, keep (1) tighter bounds on integer variables or (2)
714 // implied bound (as column bound)
715 bool updateColBound =
716 mipsolver != nullptr &&
717 ((model->integrality_[col] != HighsVarType::kContinuous &&
718 impliedBound > model->col_lower_[col] + primal_feastol) ||
719 (!useImplBound &&
720 impliedBound > model->col_lower_[col] + threshold));
721
722 // only tighten bound if it is tighter by a wide enough margin
723 if (useImplBound && impliedBound > implColLower[col] + threshold)
724 changeImplColLower(col, impliedBound, row);
725 if (updateColBound)
726 HPRESOLVE_CHECKED_CALL(changeColLower(col, impliedBound));

Callers

nothing calls this directly

Calls 5

getOrigRowIndexMethod · 0.80
indexMethod · 0.45
valueMethod · 0.45

Tested by

no test coverage detected