@@ -10,10 +10,10 @@ const bool write_model = false;
1010
1111const double inf = kHighsInf ;
1212
13- const HighsInt kIisStrategyFromRayRowPriority = kIisStrategyFromRay ;
14- const HighsInt kIisStrategyFromRayColPriority = kIisStrategyFromRay + kIisStrategyColPriority ;
15- const HighsInt kIisStrategyFromLpRowPriority = kIisStrategyFromLp ;
16- const HighsInt kIisStrategyFromLpColPriority = kIisStrategyFromLp + kIisStrategyColPriority ;
13+ const HighsInt kIisStrategyFromRayColPriority =
14+ kIisStrategyFromRay + kIisStrategyColPriority ;
15+ const HighsInt kIisStrategyFromLpColPriority =
16+ kIisStrategyFromLp + kIisStrategyColPriority ;
1717
1818void testMps (std::string& model, const HighsInt iis_strategy,
1919 const HighsModelStatus require_model_status =
@@ -58,7 +58,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
5858 REQUIRE (highs.run () == HighsStatus::kOk );
5959 REQUIRE (highs.getModelStatus () == HighsModelStatus::kInfeasible );
6060
61- highs.setOptionValue (" iis_strategy" , kIisStrategyFromLpRowPriority );
61+ highs.setOptionValue (" iis_strategy" , kIisStrategyFromLp );
6262 REQUIRE (highs.getIis (iis) == HighsStatus::kOk );
6363 REQUIRE (highs.getModelStatus () == HighsModelStatus::kInfeasible );
6464 REQUIRE (iis.valid_ == true );
@@ -100,13 +100,15 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
100100 // that just one of each (the first encountered) is found
101101 lp.col_upper_ [0 ] = -1 ;
102102 lp.row_upper_ [1 ] = -1 ;
103- const bool two_inconsistent_rows = lp.row_upper_ [0 ] < lp.row_lower_ [0 ] && lp.row_upper_ [1 ] < lp.row_lower_ [1 ];
104- const bool two_inconsistent_cols = lp.col_upper_ [0 ] < lp.col_lower_ [0 ] && lp.col_upper_ [2 ] < lp.col_lower_ [2 ];
103+ const bool two_inconsistent_rows = lp.row_upper_ [0 ] < lp.row_lower_ [0 ] &&
104+ lp.row_upper_ [1 ] < lp.row_lower_ [1 ];
105+ const bool two_inconsistent_cols = lp.col_upper_ [0 ] < lp.col_lower_ [0 ] &&
106+ lp.col_upper_ [2 ] < lp.col_lower_ [2 ];
105107 REQUIRE (two_inconsistent_cols);
106108 REQUIRE (two_inconsistent_rows);
107-
109+
108110 highs.passModel (lp);
109- highs.setOptionValue (" iis_strategy" , kIisStrategyFromLpRowPriority );
111+ highs.setOptionValue (" iis_strategy" , kIisStrategyFromLp );
110112 REQUIRE (highs.getIis (iis) == HighsStatus::kOk );
111113 REQUIRE (highs.getModelStatus () == HighsModelStatus::kInfeasible );
112114 REQUIRE (iis.valid_ == true );
@@ -243,7 +245,7 @@ TEST_CASE("lp-get-iis-light", "[iis]") {
243245 //
244246 // -10 <= 4w - 2x + y + 2z <= 15
245247 //
246- // -34 <= - 2x -1.5y - z
248+ // -34 <= - 2x -1.5y - z
247249 //
248250 Highs highs;
249251 highs.setOptionValue (" output_flag" , dev_run);
@@ -259,26 +261,28 @@ TEST_CASE("lp-get-iis-light", "[iis]") {
259261 REQUIRE (iis.row_index_ .size () == 1 );
260262 HighsInt iis_row = iis.row_index_ [0 ];
261263 if (lp.a_matrix_ .isColwise ()) {
262- for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++) {
263- for (HighsInt iEl = lp.a_matrix_ .start_ [iCol]; iEl < lp.a_matrix_ .start_ [iCol+1 ]; iEl++) {
264- if (lp.a_matrix_ .index_ [iEl] == iis_row) {
265- REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
266- break ;
267- }
268- }
269- }
264+ for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++) {
265+ for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
266+ iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
267+ if (lp.a_matrix_ .index_ [iEl] == iis_row) {
268+ REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
269+ break ;
270+ }
271+ }
272+ }
270273 } else {
271- for (HighsInt iEl = lp.a_matrix_ .start_ [iis_row]; iEl < lp.a_matrix_ .start_ [iis_row+1 ]; iEl++) {
272- HighsInt iCol = lp.a_matrix_ .index_ [iEl];
273- REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
274- }
274+ for (HighsInt iEl = lp.a_matrix_ .start_ [iis_row];
275+ iEl < lp.a_matrix_ .start_ [iis_row + 1 ]; iEl++) {
276+ HighsInt iCol = lp.a_matrix_ .index_ [iEl];
277+ REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
278+ }
275279 }
276280 for (HighsInt iRow = 0 ; iRow < lp.num_row_ ; iRow++) {
277- if (iRow == iis.row_index_ [0 ]) {
278- REQUIRE (iis.row_status_ [iRow] == kIisStatusInConflict );
279- } else {
280- REQUIRE (iis.row_status_ [iRow] == kIisStatusNotInConflict );
281- }
281+ if (iRow == iis.row_index_ [0 ]) {
282+ REQUIRE (iis.row_status_ [iRow] == kIisStatusInConflict );
283+ } else {
284+ REQUIRE (iis.row_status_ [iRow] == kIisStatusNotInConflict );
285+ }
282286 }
283287 if (dev_run && write_model) {
284288 highs.writeModel (" " );
@@ -353,24 +357,26 @@ TEST_CASE("lp-get-iis", "[iis]") {
353357 HighsInt iis_row = iis.row_index_ [0 ];
354358 if (lp.a_matrix_ .isColwise ()) {
355359 for (HighsInt iCol = 0 ; iCol < lp.num_col_ ; iCol++) {
356- for (HighsInt iEl = lp.a_matrix_ .start_ [iCol]; iEl < lp.a_matrix_ .start_ [iCol+1 ]; iEl++) {
357- if (lp.a_matrix_ .index_ [iEl] == iis_row) {
358- REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
359- break ;
360- }
361- }
360+ for (HighsInt iEl = lp.a_matrix_ .start_ [iCol];
361+ iEl < lp.a_matrix_ .start_ [iCol + 1 ]; iEl++) {
362+ if (lp.a_matrix_ .index_ [iEl] == iis_row) {
363+ REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
364+ break ;
365+ }
366+ }
362367 }
363368 } else {
364- for (HighsInt iEl = lp.a_matrix_ .start_ [iis_row]; iEl < lp.a_matrix_ .start_ [iis_row+1 ]; iEl++) {
365- HighsInt iCol = lp.a_matrix_ .index_ [iEl];
366- REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
369+ for (HighsInt iEl = lp.a_matrix_ .start_ [iis_row];
370+ iEl < lp.a_matrix_ .start_ [iis_row + 1 ]; iEl++) {
371+ HighsInt iCol = lp.a_matrix_ .index_ [iEl];
372+ REQUIRE (iis.col_status_ [iCol] == kIisStatusInConflict );
367373 }
368374 }
369375 for (HighsInt iRow = 0 ; iRow < lp.num_row_ ; iRow++) {
370376 if (iRow == iis.row_index_ [0 ]) {
371- REQUIRE (iis.row_status_ [iRow] == kIisStatusInConflict );
377+ REQUIRE (iis.row_status_ [iRow] == kIisStatusInConflict );
372378 } else {
373- REQUIRE (iis.row_status_ [iRow] == kIisStatusNotInConflict );
379+ REQUIRE (iis.row_status_ [iRow] == kIisStatusNotInConflict );
374380 }
375381 }
376382 highs.clearSolver ();
@@ -382,8 +388,12 @@ TEST_CASE("lp-get-iis", "[iis]") {
382388
383389TEST_CASE (" lp-get-iis-woodinfe" , " [iis]" ) {
384390 std::string model = " woodinfe" ;
385- testMps (model, kIisStrategyFromLpRowPriority );
386- // testMps(model, kIisStrategyFromRayRowPriority);
391+ testMps (model, kIisStrategyLight );
392+ testMps (model, kIisStrategyFromLp );
393+ // testMps(model, kIisStrategyFromRay);
394+ //
395+ // No need for a +kIisStrategyIrreducible test, since kIisStrategyFromLp
396+ // yields IIS
387397}
388398
389399TEST_CASE (" lp-get-iis-galenet" , " [iis]" ) {
@@ -407,7 +417,7 @@ TEST_CASE("lp-get-iis-galenet", "[iis]") {
407417 //
408418 // 0 <= c4 <= 30
409419 //
410- // This is infeasible since c4 >= 30 and c4 <= 30 fices c4 = 30,
420+ // This is infeasible since c4 >= 30 and c4 <= 30 fixes c4 = 30,
411421 // then c0 + c1 >= c3 + c4 >= 30 cannot be satisfied due to the
412422 // upper bounds of 10 on these variables
413423 //
@@ -427,19 +437,36 @@ TEST_CASE("lp-get-iis-galenet", "[iis]") {
427437 // r2 that makes r0 infeasible
428438 //
429439 // Hence only empty columns can be removed
440+ //
441+ // If the elasticity filter is used, then it identifies the
442+ // following infeasibility system
443+ //
444+ // r4: 0 <= c2 + c3 - c6 - c7
445+ //
446+ // r6: 20 <= c5 + c6
447+ //
448+ // r7: 30 <= c7
449+ //
450+ // This is infeasible since c7 >= 30 gives 30 <= c2 + c3, but c2 and
451+ // c3 have upper bounds of 10
452+ //
453+ // Hence the IIS does not require r6 or c5, and consists of r4 and r7
454+ // (>=0) with c2 <= 10; c3 <= 10; c6 free; c7 free
455+
430456 std::string model = " galenet" ;
431- testMps (model, kIisStrategyFromLpRowPriority );
432- // testMps(model, kIisStrategyFromLpRowPriority + kIisStrategyIrreducible);
457+ testMps (model, kIisStrategyLight , HighsModelStatus::kNotset );
458+ testMps (model, kIisStrategyFromLp );
459+ testMps (model, kIisStrategyFromLp + kIisStrategyIrreducible );
433460}
434461
435462TEST_CASE (" lp-get-iis-avgas" , " [iis]" ) {
436463 std::string model = " avgas" ;
437464 // For the whole LP calculation the elasticity filter only
438465 // identified feasibility, so the model status is not set
439- testMps (model, kIisStrategyFromLpRowPriority , HighsModelStatus::kNotset );
466+ testMps (model, kIisStrategyFromLp , HighsModelStatus::kNotset );
440467 // For the ray calculation the model is solved, so its status is
441468 // known
442- // testMps(model, kIisStrategyFromRayRowPriority ,
469+ // testMps(model, kIisStrategyFromRay ,
443470 // HighsModelStatus::kOptimal);
444471}
445472
@@ -562,7 +589,7 @@ void testMps(std::string& model, const HighsInt iis_strategy,
562589 // highs.setOptionValue("output_flag", dev_run);
563590
564591 REQUIRE (highs.readModel (model_file) == HighsStatus::kOk );
565- // if (iis_strategy == kIisStrategyFromRayRowPriority ||
592+ // if (iis_strategy == kIisStrategyFromRay ||
566593 // iis_strategy == kIisStrategyFromRayColPriority) {
567594 // // For a ray strategy, solve the LP first
568595 // REQUIRE(highs.run() == HighsStatus::kOk);
@@ -586,11 +613,12 @@ void testMps(std::string& model, const HighsInt iis_strategy,
586613 int (num_iis_col), int (num_iis_row));
587614 REQUIRE (iis.valid_ == true );
588615 const bool find_irreducible = kIisStrategyIrreducible & iis_strategy;
589- const HighsInt iis_status = find_irreducible ? kIisStatusInConflict : kIisStatusMaybeInConflict ;
590- REQUIRE (iis.irreducible_ == find_irreducible);
591- for (HighsInt iX = 0 ; iX < num_iis_col; iX++)
616+ if (find_irreducible) REQUIRE (iis.irreducible_ );
617+ const HighsInt iis_status =
618+ iis.irreducible_ ? kIisStatusInConflict : kIisStatusMaybeInConflict ;
619+ for (HighsInt iX = 0 ; iX < num_iis_col; iX++)
592620 REQUIRE (iis.col_status_ [iis.col_index_ [iX]] == iis_status);
593- for (HighsInt iX = 0 ; iX < num_iis_row; iX++)
621+ for (HighsInt iX = 0 ; iX < num_iis_row; iX++)
594622 REQUIRE (iis.row_status_ [iis.row_index_ [iX]] == iis_status);
595623 } else {
596624 REQUIRE (num_iis_col == 0 );
@@ -656,7 +684,7 @@ TEST_CASE("feasible-lp-iis", "[iis]") {
656684
657685 h.passModel (lp);
658686 // With kIisStrategyFromLp, feasibility of the LP is determined
659- h.setOptionValue (" iis_strategy" , kIisStrategyFromLpRowPriority );
687+ h.setOptionValue (" iis_strategy" , kIisStrategyFromLp );
660688
661689 h.getIis (iis);
662690 REQUIRE (iis.col_index_ .size () == 0 );
0 commit comments