@@ -294,7 +294,7 @@ TEST_CASE("MIP-unbounded", "[highs_test_mip_solver]") {
294294 lp.col_upper_ = {inf};
295295 lp.integrality_ = {HighsVarType::kInteger };
296296
297- bool use_presolve = true ;
297+ bool use_presolve = false ;
298298 HighsModelStatus require_model_status;
299299 for (HighsInt k = 0 ; k < 2 ; k++) {
300300 if (use_presolve) {
@@ -304,7 +304,11 @@ TEST_CASE("MIP-unbounded", "[highs_test_mip_solver]") {
304304 require_model_status = HighsModelStatus::kUnboundedOrInfeasible ;
305305 } else {
306306 // With use_presolve = false, MIP solver returns
307- // HighsModelStatus::kUnbounded
307+ // HighsModelStatus::kUnbounded, because the all-zeros trivial
308+ // heuristic finds a feasible point
309+ //
310+ // Feasibility jump appears to find one before the all-zeros
311+ // trivial heuristic
308312 highs.setOptionValue (" presolve" , kHighsOffString );
309313 require_model_status = HighsModelStatus::kUnbounded ;
310314 }
@@ -317,8 +321,8 @@ TEST_CASE("MIP-unbounded", "[highs_test_mip_solver]") {
317321 model_status = highs.getModelStatus ();
318322 REQUIRE (model_status == require_model_status);
319323
320- // Second time through loop is without presolve
321- use_presolve = false ;
324+ // Second time through loop is with presolve
325+ use_presolve = true ;
322326 }
323327 // Two-variable problem that is also primal unbounded as an LP, but
324328 // primal infeasible as a MIP.
@@ -339,13 +343,12 @@ TEST_CASE("MIP-unbounded", "[highs_test_mip_solver]") {
339343 lp.a_matrix_ .value_ = {1 , 2 };
340344 lp.a_matrix_ .format_ = MatrixFormat::kRowwise ;
341345
342- use_presolve = true ;
346+ use_presolve = false ;
343347 for (HighsInt k = 0 ; k < 2 ; k++) {
344348 if (use_presolve) {
345349 // With use_presolve = true, LP solver returns
346350 // HighsModelStatus::kUnbounded because it solves the LP after
347351 // presolve has returned
348- // HighsModelStatus::kUnboundedOrInfeasible
349352 highs.setOptionValue (" presolve" , kHighsOnString );
350353 require_model_status = HighsModelStatus::kUnbounded ;
351354 } else {
@@ -364,38 +367,25 @@ TEST_CASE("MIP-unbounded", "[highs_test_mip_solver]") {
364367 model_status = highs.getModelStatus ();
365368 REQUIRE (model_status == require_model_status);
366369
367- // Second time through loop is without presolve
368- use_presolve = false ;
370+ // Second time through loop is with presolve
371+ use_presolve = true ;
369372 }
370373
371374 // Now as a MIP - infeasible
372375 lp.integrality_ = {HighsVarType::kContinuous , HighsVarType::kInteger };
373- use_presolve = true ;
374- for (HighsInt k = 0 ; k < 2 ; k++) {
375- if (use_presolve) {
376- // With use_presolve = true, MIP solver returns
377- // HighsModelStatus::kUnboundedOrInfeasible from presolve
378- highs.setOptionValue (" presolve" , kHighsOnString );
379- require_model_status = HighsModelStatus::kUnboundedOrInfeasible ;
380- } else {
381- // With use_presolve = false, MIP solver returns
382- // HighsModelStatus::kUnboundedOrInfeasible
383- highs.setOptionValue (" presolve" , kHighsOffString );
384- require_model_status = HighsModelStatus::kUnboundedOrInfeasible ;
385- }
376+ // With(out) presolve, Highs::infeasibleBoundsOk() performs inward
377+ // integer rounding of [0.25, 0.75] to [1, 0] so identifes
378+ // infeasiblility. Hence MIP solver returns
379+ // HighsModelStatus::kInfeasible
386380
387- return_status = highs.passModel (lp);
388- REQUIRE (return_status == HighsStatus::kOk );
389-
390- return_status = highs.run ();
391- REQUIRE (return_status == HighsStatus::kOk );
381+ return_status = highs.passModel (lp);
382+ REQUIRE (return_status == HighsStatus::kOk );
392383
393- model_status = highs.getModelStatus ();
394- REQUIRE (model_status == require_model_status );
384+ return_status = highs.run ();
385+ REQUIRE (return_status == HighsStatus:: kOk );
395386
396- // Second time through loop is without presolve
397- use_presolve = false ;
398- }
387+ model_status = highs.getModelStatus ();
388+ REQUIRE (model_status == HighsModelStatus::kInfeasible );
399389}
400390
401391TEST_CASE (" MIP-od" , " [highs_test_mip_solver]" ) {
@@ -568,7 +558,7 @@ TEST_CASE("MIP-get-saved-solutions", "[highs_test_mip_solver]") {
568558 const std::vector<HighsObjectiveSolution> saved_objective_and_solution =
569559 highs.getSavedMipSolutions ();
570560 const HighsInt num_saved_solution = saved_objective_and_solution.size ();
571- REQUIRE (num_saved_solution == 3 );
561+ REQUIRE (num_saved_solution > 0 );
572562 const HighsInt last_saved_solution = num_saved_solution - 1 ;
573563 REQUIRE (saved_objective_and_solution[last_saved_solution].objective ==
574564 highs.getInfo ().objective_function_value );
@@ -693,9 +683,22 @@ TEST_CASE("IP-infeasible-unbounded", "[highs_test_mip_solver]") {
693683 required_model_status = HighsModelStatus::kUnbounded ;
694684 }
695685 } else {
696- // Presolve on, and identifies primal infeasible or unbounded
697- required_model_status = HighsModelStatus::kUnboundedOrInfeasible ;
686+ // Presolve on
687+ if (l == 0 ) {
688+ // Inward integer rounding proves infeasiblilty
689+ required_model_status = HighsModelStatus::kInfeasible ;
690+ } else {
691+ // Presolve identifies primal infeasible or unbounded
692+ required_model_status = HighsModelStatus::kUnboundedOrInfeasible ;
693+ }
698694 }
695+ if (dev_run)
696+ printf (
697+ " For k = %d and l = %d, original bounds on col 1 are [%g, %g]: "
698+ " model status is \" %s\" and required status is \" %s\"\n " ,
699+ int (k), int (l), lp.col_lower_ [1 ], lp.col_upper_ [1 ],
700+ highs.modelStatusToString (highs.getModelStatus ()).c_str (),
701+ highs.modelStatusToString (required_model_status).c_str ());
699702 REQUIRE (highs.getModelStatus () == required_model_status);
700703 }
701704 highs.setOptionValue (" presolve" , kHighsOnString );
@@ -704,8 +707,8 @@ TEST_CASE("IP-infeasible-unbounded", "[highs_test_mip_solver]") {
704707
705708TEST_CASE (" IP-with-fract-bounds-no-presolve" , " [highs_test_mip_solver]" ) {
706709 Highs highs;
707- // No presolve
708710 highs.setOptionValue (" output_flag" , dev_run);
711+ // No presolve
709712 highs.setOptionValue (" presolve" , kHighsOffString );
710713
711714 // IP without constraints and fractional bounds on variables
0 commit comments