@@ -1154,6 +1154,65 @@ TEST_CASE("add-to-matrix", "[highs_test_presolve]") {
11541154 h.resetGlobalScheduler (true );
11551155}
11561156
1157+ TEST_CASE (" max-lp-dual-postsolve" , " [highs_test_presolve]" ) {
1158+ Highs h;
1159+ h.setOptionValue (" output_flag" , dev_run);
1160+
1161+ // Start with blending problem
1162+ HighsLp lp;
1163+ lp.model_name_ = " blending" ;
1164+ lp.num_col_ = 2 ;
1165+ lp.num_row_ = 2 ;
1166+ lp.col_cost_ = {8 , 10 };
1167+ lp.col_lower_ = {0 , 0 };
1168+ lp.col_upper_ = {inf, inf};
1169+ lp.row_lower_ = {-inf, -inf};
1170+ lp.row_upper_ = {120 , 210 };
1171+ lp.a_matrix_ .format_ = MatrixFormat::kColwise ;
1172+ lp.a_matrix_ .start_ = {0 , 2 , 4 };
1173+ lp.a_matrix_ .index_ = {0 , 1 , 0 , 1 };
1174+ lp.a_matrix_ .value_ = {0.3 , 0.7 , 0.5 , 0.5 };
1175+ lp.sense_ = ObjSense::kMaximize ;
1176+ lp.offset_ = 0 ;
1177+ h.passModel (lp);
1178+
1179+ REQUIRE (h.setOptionValue (" solver" , kIpxString ) == HighsStatus::kOk );
1180+ REQUIRE (h.setOptionValue (" run_crossover" , kHighsOffString ) ==
1181+ HighsStatus::kOk );
1182+
1183+ h.run ();
1184+ if (dev_run) h.writeSolution (" " , kSolutionStylePretty );
1185+ REQUIRE (h.getModelStatus () == HighsModelStatus::kOptimal );
1186+
1187+ double optimal_objective = h.getObjectiveValue ();
1188+ HighsSolution solution = h.getSolution ();
1189+
1190+ // Add a redundant constraint that's removed in presolve so that
1191+ // postsolve must be performed
1192+ std::vector<HighsInt> index = {0 , 1 };
1193+ std::vector<double > value = {1 , 1 };
1194+ REQUIRE (h.addRow (-inf, 1000 , 2 , index.data (), value.data ()) ==
1195+ HighsStatus::kOk );
1196+ h.clearSolver ();
1197+
1198+ h.run ();
1199+ if (dev_run) h.writeSolution (" " , kSolutionStylePretty );
1200+ REQUIRE (h.getModelStatus () == HighsModelStatus::kOptimal );
1201+
1202+ REQUIRE (doubleEqual (optimal_objective, h.getObjectiveValue ()));
1203+ // Check that the dual values are unchanged for the original problem
1204+ for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++)
1205+ REQUIRE (
1206+ doubleEqual (solution.col_dual [iCol], h.getSolution ().col_dual [iCol]));
1207+ for (HighsInt iRow = 0 ; iRow < lp.num_row_ ; iRow++)
1208+ REQUIRE (
1209+ doubleEqual (solution.row_dual [iRow], h.getSolution ().row_dual [iRow]));
1210+
1211+ REQUIRE (h.getModelStatus () == HighsModelStatus::kOptimal );
1212+
1213+ h.resetGlobalScheduler (true );
1214+ }
1215+
11571216TEST_CASE (" issue-3140" , " [highs_test_presolve]" ) {
11581217 Highs highs;
11591218 highs.setOptionValue (" output_flag" , dev_run);
0 commit comments