diff --git a/check/TestMipSolver.cpp b/check/TestMipSolver.cpp index 2cd1c9b2b62..59141e831c0 100644 --- a/check/TestMipSolver.cpp +++ b/check/TestMipSolver.cpp @@ -1729,3 +1729,15 @@ TEST_CASE("issue-3171", "[highs_test_mip_solver]") { const double optimal_objective = 42215.5250005; solve(highs, kHighsOnString, require_model_status, optimal_objective); } + +TEST_CASE("issue-2900", "[highs_test_mip_solver]") { + std::string filename = + std::string(HIGHS_DIR) + "/check/instances/issue-2900.mps"; + Highs highs; + highs.setOptionValue("output_flag", dev_run); + highs.readModel(filename); + const HighsModelStatus require_model_status = HighsModelStatus::kOptimal; + const double optimal_objective = 294856559.369; + solve(highs, kHighsOffString, require_model_status, optimal_objective); + solve(highs, kHighsOnString, require_model_status, optimal_objective); +} diff --git a/check/instances/issue-2900.mps b/check/instances/issue-2900.mps new file mode 100644 index 00000000000..504a66ee18c --- /dev/null +++ b/check/instances/issue-2900.mps @@ -0,0 +1,296 @@ +NAME dbg-presolve-1 +OBJSENSE + MAX +ROWS + N obj + L con44 + L con46 + L con52 + L con54 + L con64 + L con66 + L con80 + L con171 + L con192 + L con212 + L con230 + L con234 + L con236 + L con239 + L con240 + L con241 + L con242 + L con248 + L con249 + L con254 + L con258 + L con262 + L con263 + L con264 + L con269 + L con271 + L con272 + L con273 + L con312 + L con315 + L con324 + L con325 + L con326 + L con328 + L con330 + L con332 + L con334 + L con338 + L con340 + L con341 + L con344 +COLUMNS + MARK0000 'MARKER' 'INTORG' + x21 obj 3998299.40984221 + x21 con44 1 + x21 con325 4732482.558 + x21 con326 5123530.786336 + x21 con328 -5123530.786336 + x22 obj 948593.366078137 + x22 con46 1 + x22 con325 670767.42 + x22 con326 1076039.08944 + x22 con328 -1076039.08944 + x23 obj 32782837.5853637 + x23 con325 34032003.216 + x23 con326 26900012.71832 + x23 con328 -26900012.71832 + x25 obj 3634817.64531112 + x25 con44 -1 + x25 con52 1 + x25 con328 5123530.786336 + x25 con330 -5123530.786336 + x26 obj 862357.605525579 + x26 con46 -1 + x26 con54 1 + x26 con328 1076039.08944 + x26 con330 -1076039.08944 + x30 obj 3301160.85951881 + x30 con52 -1 + x30 con64 1 + x30 con330 5118710.050336 + x30 con332 -5118710.050336 + x31 obj 783961.459568708 + x31 con54 -1 + x31 con66 1 + x31 con330 1076039.08944 + x31 con332 -1076039.08944 + x36 obj 292846.252029092 + x36 con66 -1 + x36 con80 1 + x36 con332 334830.128 + x36 con334 -334830.128 + x78 obj 3365013.82472729 + x78 con171 1 + x89 obj 8291243.57714889 + x89 con171 -1 + x89 con192 1 + x89 con324 -15488593.38816 + x99 obj 14314309.3740774 + x99 con192 -1 + x99 con212 1 + x99 con324 23480239.71792 + x99 con325 -23472544.668 + x99 con326 -23480239.71792 + x108 obj 19280162.3671442 + x108 con212 -1 + x108 con230 1 + x108 con325 31229304.402 + x108 con326 31474453.447504 + x108 con328 -31474453.447504 + x109 obj 113581.069599071 + x109 con234 1 + x109 con325 128405.31 + x109 con326 123255.288 + x109 con328 -123255.288 + x110 obj 94075.7138378525 + x110 con236 1 + x110 con325 105261.984 + x110 con326 98075.1152 + x110 con328 -98075.1152 + x112 obj 55719.6673724472 + x112 con239 1 + x112 con325 54934.482 + x112 con326 54141.2752 + x112 con328 -54141.2752 + x113 obj 13375.9510962366 + x113 con240 1 + x113 con325 13808.406 + x113 con326 12608.096 + x113 con328 -12608.096 + x114 obj 4891.49989754798 + x114 con241 1 + x114 con325 4546.776 + x114 con326 4457.12 + x114 con328 -4457.12 + x115 obj 63520.668328666 + x115 con242 1 + x115 con325 64920.006 + x115 con326 56577.2896 + x115 con328 -56577.2896 + x117 obj 24478879.1662204 + x117 con230 -1 + x117 con328 39109563.257104 + x117 con330 -39109563.257104 + x118 obj 103255.517817337 + x118 con234 -1 + x118 con248 1 + x118 con328 123255.288 + x118 con330 -123255.288 + x119 obj 85523.3762162297 + x119 con236 -1 + x119 con249 1 + x119 con328 98075.1152 + x119 con330 -98075.1152 + x122 obj 3218.81803674839 + x122 con64 -1 + x122 con254 1 + x122 con330 4820.736 + x122 con332 -4820.736 + x124 obj 30090487.0217221 + x124 con330 45934344.835584 + x124 con332 -45934344.835584 + x125 obj 93868.6525612158 + x125 con248 -1 + x125 con258 1 + x125 con330 123255.288 + x125 con332 -123255.288 + x127 obj 86009.7259627886 + x127 con254 -1 + x127 con262 1 + x127 con332 194246.248 + x127 con334 -194246.248 + x128 obj 419845.983942462 + x128 con80 -1 + x128 con263 1 + x128 con332 741208.96144 + x128 con334 -741208.96144 + x129 obj 828924.762860659 + x129 con263 -1 + x129 con264 1 + x129 con332 820689.27792 + x129 con334 -820689.27792 + x130 obj 34101426.3823695 + x130 con264 -1 + x130 con332 53273672.877664 + x130 con334 -53273672.877664 + x132 obj 140312.917802552 + x132 con262 -1 + x132 con269 1 + x132 con334 314960 + x134 obj 588701.185419978 + x134 con269 -1 + x134 con271 1 + x134 con334 1242727.9096 + x135 obj 84634.7093148896 + x135 con271 -1 + x135 con272 1 + x135 con334 166727.696 + x136 obj 661850.998746351 + x136 con272 -1 + x136 con273 1 + x136 con334 1300206.611136 + x145 obj 70396781.0225298 + x145 con249 -1 + x145 con258 -1 + x145 con273 -1 + x145 con330 98075.1152 + x145 con332 123255.288 + x145 con334 57928799.5496639 + x145 con338 -64212075.1087999 + x153 obj 32498556.0666157 + x153 con239 -1 + x153 con328 54141.2752 + x153 con330 12608.272 + x153 con338 64689933.6767999 + x153 con340 -64756683.2239999 + x161 obj 29461815.6595683 + x161 con240 -1 + x161 con328 12608.096 + x161 con340 64862115.9919999 + x161 con341 -70975247.8919999 + x162 obj 23813.8701479657 + x162 con241 -1 + x162 con312 1 + x162 con328 4457.12 + x162 con341 -4546.776 + x165 obj 545922.19650717 + x165 con315 1 + x165 con341 7461767.634 + x165 con344 -4093857.73264 + x166 obj 5821274.06994406 + x166 con315 -1 + x166 con341 25807684.122 + x166 con344 -25134012.408464 + x167 obj 26730509.0049454 + x167 con341 70975247.8919999 + x167 con344 -64874724.0879999 + x169 obj 343885861.067442 + x169 con242 -1 + x169 con312 -1 + x169 con324 51215.92 + x169 con325 98531.046 + x169 con326 86469.9104 + x169 con328 56577.2896 + x169 con341 4546.776 + x169 con344 101664243.63264 + MARK0001 'MARKER' 'INTEND' +RHS + RHS_V con324 8000000 + RHS_V con325 18000000 + RHS_V con326 8000000 + RHS_V con328 8000000 + RHS_V con330 8000000 + RHS_V con332 8000000 + RHS_V con334 8000000 + RHS_V con338 8000000 + RHS_V con340 8000000 + RHS_V con341 18000000 + RHS_V con344 8000000 +BOUNDS + BV BOUND x21 + BV BOUND x22 + BV BOUND x23 + BV BOUND x25 + BV BOUND x26 + BV BOUND x30 + BV BOUND x31 + BV BOUND x36 + BV BOUND x78 + BV BOUND x89 + BV BOUND x99 + BV BOUND x108 + BV BOUND x109 + BV BOUND x110 + BV BOUND x112 + BV BOUND x113 + BV BOUND x114 + BV BOUND x115 + BV BOUND x117 + BV BOUND x118 + BV BOUND x119 + BV BOUND x122 + BV BOUND x124 + BV BOUND x125 + BV BOUND x127 + BV BOUND x128 + BV BOUND x129 + BV BOUND x130 + BV BOUND x132 + BV BOUND x134 + BV BOUND x135 + BV BOUND x136 + BV BOUND x145 + BV BOUND x153 + BV BOUND x161 + BV BOUND x162 + BV BOUND x165 + BV BOUND x166 + BV BOUND x167 + BV BOUND x169 +ENDATA diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp index 7f8f4725d0a..614fdf90d83 100644 --- a/highs/presolve/HPresolve.cpp +++ b/highs/presolve/HPresolve.cpp @@ -7994,8 +7994,8 @@ HPresolve::Result HPresolve::removeDoubletonEquations( HPresolve::Result HPresolve::strengthenInequalities( HighsPostsolveStack& postsolve_stack, HighsInt& num_strengthened) { std::vector complementation; - std::vector reducedcost; - std::vector upper; + std::vector reducedcost; + std::vector upper; std::vector indices; std::vector positions; std::vector stack; @@ -8072,7 +8072,8 @@ HPresolve::Result HPresolve::strengthenInequalities( // activity. int8_t comp; double weight = Avalue[pos] * scale; - double ub = model->col_upper_[col] - model->col_lower_[col]; + HighsCDouble ub = static_cast(model->col_upper_[col]) - + static_cast(model->col_lower_[col]); if (weight > 0) { comp = 1; maxviolation += @@ -8135,7 +8136,7 @@ HPresolve::Result HPresolve::strengthenInequalities( for (size_t i = indices.size(); i > 0; --i) { HighsInt index = indices[i - 1]; - double delta = upper[index] * reducedcost[index]; + HighsCDouble delta = upper[index] * reducedcost[index]; if (upper[index] <= 1000.0 && reducedcost[index] > smallVal && lambda - delta <= smallVal) @@ -8153,26 +8154,25 @@ HPresolve::Result HPresolve::strengthenInequalities( return reducedcost[i1] < reducedcost[i2]; }); - double al = reducedcost[alpos]; + HighsCDouble al = reducedcost[alpos]; coefs.resize(cover.size()); - double coverrhs = std::max( - std::ceil(static_cast(lambda / al - primal_feastol)), 1.0); + HighsCDouble coverrhs = max(ceil(lambda / al - primal_feastol), 1.0); HighsCDouble slackupper = -coverrhs; - double step = kHighsInf; + HighsCDouble step = kHighsInf; for (size_t i = 0; i != cover.size(); ++i) { - coefs[i] = std::ceil( - std::min(reducedcost[cover[i]], static_cast(lambda)) / al - - options->small_matrix_value); + coefs[i] = + static_cast(ceil(min(reducedcost[cover[i]], lambda) / al - + options->small_matrix_value)); slackupper += upper[cover[i]] * coefs[i]; - step = std::min(step, reducedcost[cover[i]] / coefs[i]); + step = min(step, reducedcost[cover[i]] / coefs[i]); } - step = std::min(step, static_cast(maxviolation / coverrhs)); + step = min(step, maxviolation / coverrhs); maxviolation -= step * coverrhs; HighsInt slackind = reducedcost.size(); reducedcost.push_back(step); - upper.push_back(static_cast(slackupper)); + upper.push_back(slackupper); for (size_t i = 0; i != cover.size(); ++i) reducedcost[cover[i]] -= step * coefs[i]; @@ -8191,7 +8191,7 @@ HPresolve::Result HPresolve::strengthenInequalities( [&](HighsInt i) { return static_cast(i) >= positions.size() || - std::abs(reducedcost[i]) <= threshold; + abs(reducedcost[i]) <= threshold; }), indices.end()); if (indices.empty()) continue; diff --git a/highs/util/HighsCDouble.h b/highs/util/HighsCDouble.h index 4b2592b4dd5..f689618b6b3 100644 --- a/highs/util/HighsCDouble.h +++ b/highs/util/HighsCDouble.h @@ -318,6 +318,14 @@ class HighsCDouble { friend HighsCDouble ldexp(const HighsCDouble& v, int exp) { return HighsCDouble(std::ldexp(v.hi, exp), std::ldexp(v.lo, exp)); } + + friend const HighsCDouble& min(const HighsCDouble& a, const HighsCDouble& b) { + return a < b ? a : b; + } + + friend const HighsCDouble& max(const HighsCDouble& a, const HighsCDouble& b) { + return a > b ? a : b; + } }; #endif