@@ -829,3 +829,44 @@ void HighsImplications::cleanupVub(HighsInt col, HighsInt vubCol,
829829 infeasible = mipsolver.mipdata_ ->domain .infeasible ();
830830 }
831831}
832+
833+ void HighsImplications::applyImplications (HighsDomain& domain,
834+ const HighsInt col,
835+ const HighsInt val) {
836+ assert (domain.isFixed (col));
837+
838+ auto checkImplication = [&](const HighsDomainChange& domchg) -> bool {
839+ assert (!domain.infeasible ());
840+ if (domain.isFixed (domchg.column )) return false ;
841+ const bool isint =
842+ domain.variableType (domchg.column ) != HighsVarType::kContinuous ;
843+ // Directly change bounds on all integer columns. Only change continuous
844+ // columns that fix the column, as changing their domains risks
845+ // suppressing further bound changes found in propagation, e.g.,
846+ // change [0, 100] -> [0, 50], propagation could tighten to [0, 48], but
847+ // such a tightening would not be applied due to min boundRange improvement.
848+ if (domchg.boundtype == HighsBoundType::kLower ) {
849+ if ((!isint && domchg.boundval >
850+ domain.col_upper_ [domchg.column ] - domain.feastol ()) ||
851+ (isint && domchg.boundval >
852+ domain.col_lower_ [domchg.column ] + domain.feastol ())) {
853+ domain.changeBound (domchg, HighsDomain::Reason::cliqueTable (col, val));
854+ }
855+ } else {
856+ if ((!isint && domchg.boundval <
857+ domain.col_lower_ [domchg.column ] + domain.feastol ()) ||
858+ (isint && domchg.boundval <
859+ domain.col_upper_ [domchg.column ] - domain.feastol ())) {
860+ domain.changeBound (domchg, HighsDomain::Reason::cliqueTable (col, val));
861+ }
862+ }
863+ return domain.infeasible ();
864+ };
865+
866+ HighsInt loc = 2 * col + val;
867+ if (implications[loc].computed ) {
868+ for (HighsDomainChange& domchg : implications[loc].implics ) {
869+ if (checkImplication (domchg)) break ;
870+ }
871+ }
872+ }
0 commit comments