Skip to content

Commit b7fe821

Browse files
committed
lp-empty-infeasible-row passes
1 parent 9fda01e commit b7fe821

File tree

2 files changed

+61
-19
lines changed

2 files changed

+61
-19
lines changed

check/TestIis.cpp

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
4242
lp.a_matrix_.index_ = {1, 2, 0, 2};
4343
lp.a_matrix_.value_ = {1, 1, 1, 1};
4444
Highs highs;
45-
// highs.setOptionValue("output_flag", dev_run);
45+
highs.setOptionValue("output_flag", dev_run);
4646
highs.passModel(lp);
4747
// Perform the light IIS check
4848
highs.setOptionValue("iis_strategy", kIisStrategyLight);
@@ -87,7 +87,7 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
8787
lp.a_matrix_.index_ = {0, 1, 0, 1};
8888
lp.a_matrix_.value_ = {2, 1, 1, 3};
8989
Highs highs;
90-
highs.setOptionValue("output_flag", dev_run);
90+
// highs.setOptionValue("output_flag", dev_run);
9191
highs.passModel(lp);
9292
REQUIRE(highs.run() == HighsStatus::kOk);
9393
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
@@ -97,7 +97,13 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
9797
REQUIRE(iis.row_index_.size() == 1);
9898
REQUIRE(iis.row_index_[0] == empty_row);
9999
REQUIRE(iis.row_bound_[0] == kIisBoundStatusLower);
100-
REQUIRE(highs.changeRowBounds(empty_row, -2, -1) == HighsStatus::kOk);
100+
double new_lower = -2;
101+
double new_upper = -1;
102+
assert(new_upper < 0);
103+
REQUIRE(highs.changeRowBounds(empty_row, new_lower, new_upper) ==
104+
HighsStatus::kOk);
105+
lp.row_lower_[empty_row] = new_lower;
106+
lp.row_upper_[empty_row] = new_upper;
101107
REQUIRE(highs.run() == HighsStatus::kOk);
102108
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
103109
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
@@ -106,6 +112,16 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
106112
REQUIRE(iis.row_index_[0] == empty_row);
107113
REQUIRE(iis.row_bound_[0] == kIisBoundStatusUpper);
108114

115+
HighsLp iis_lp;
116+
REQUIRE(highs.getIisLp(iis_lp) == HighsStatus::kOk);
117+
highs.writeModel("");
118+
119+
printf("\nNow pass IIS LP\n");
120+
highs.passModel(iis_lp);
121+
highs.writeModel("");
122+
123+
checkIisLp(lp, iis, iis_lp);
124+
109125
highs.resetGlobalScheduler(true);
110126
}
111127

@@ -493,14 +509,21 @@ void checkIisLp(HighsLp& lp, const HighsIis& iis, const HighsLp& iis_lp) {
493509
lp.a_matrix_.ensureColwise();
494510
std::vector<HighsInt> iis_row;
495511
iis_row.assign(lp.num_row_, -1);
512+
double bound;
496513
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++) {
497514
HighsInt iRow = iis.row_index_[iisRow];
498515
iis_row[iRow] = iisRow;
499516
HighsInt row_bound = iis.row_bound_[iisRow];
500-
if (row_bound == kIisBoundStatusLower || row_bound == kIisBoundStatusBoxed)
501-
REQUIRE(iis_lp.row_lower_[iisRow] == lp.row_lower_[iRow]);
502-
if (row_bound == kIisBoundStatusUpper || row_bound == kIisBoundStatusBoxed)
503-
REQUIRE(iis_lp.row_upper_[iisRow] == lp.row_upper_[iRow]);
517+
bound =
518+
row_bound == kIisBoundStatusLower || row_bound == kIisBoundStatusBoxed
519+
? lp.row_lower_[iRow]
520+
: -kHighsInf;
521+
REQUIRE(iis_lp.row_lower_[iisRow] == bound);
522+
bound =
523+
row_bound == kIisBoundStatusUpper || row_bound == kIisBoundStatusBoxed
524+
? lp.row_upper_[iRow]
525+
: kHighsInf;
526+
REQUIRE(iis_lp.row_upper_[iisRow] == bound);
504527
}
505528

506529
// Work through the LP columns and matrix, checking the costs,
@@ -509,10 +532,16 @@ void checkIisLp(HighsLp& lp, const HighsIis& iis, const HighsLp& iis_lp) {
509532
HighsInt iCol = iis.col_index_[iisCol];
510533
REQUIRE(iis_lp.col_cost_[iisCol] == lp.col_cost_[iCol]);
511534
HighsInt col_bound = iis.col_bound_[iisCol];
512-
if (col_bound == kIisBoundStatusLower || col_bound == kIisBoundStatusBoxed)
513-
REQUIRE(iis_lp.col_lower_[iisCol] == lp.col_lower_[iCol]);
514-
if (col_bound == kIisBoundStatusUpper || col_bound == kIisBoundStatusBoxed)
515-
REQUIRE(iis_lp.col_upper_[iisCol] == lp.col_upper_[iCol]);
535+
bound =
536+
col_bound == kIisBoundStatusLower || col_bound == kIisBoundStatusBoxed
537+
? lp.col_lower_[iCol]
538+
: -kHighsInf;
539+
REQUIRE(iis_lp.col_lower_[iisCol] == bound);
540+
bound =
541+
col_bound == kIisBoundStatusUpper || col_bound == kIisBoundStatusBoxed
542+
? lp.col_upper_[iCol]
543+
: kHighsInf;
544+
REQUIRE(iis_lp.col_upper_[iisCol] == bound);
516545
for (HighsInt iEl = lp.a_matrix_.start_[iCol];
517546
iEl < lp.a_matrix_.start_[iCol + 1]; iEl++) {
518547
HighsInt iRow = lp.a_matrix_.index_[iEl];

highs/lp_data/Highs.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,24 +1961,37 @@ HighsStatus Highs::getIisLp(HighsLp& iis_lp) {
19611961
lp.a_matrix_.ensureColwise();
19621962
std::vector<HighsInt> iis_row;
19631963
iis_row.assign(lp.num_row_, -1);
1964+
double bound;
19641965
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++) {
19651966
HighsInt iRow = this->iis_.row_index_[iisRow];
19661967
iis_row[iRow] = iisRow;
19671968
HighsInt row_bound = this->iis_.row_bound_[iisRow];
1968-
if (row_bound == kIisBoundStatusLower || row_bound == kIisBoundStatusBoxed)
1969-
iis_lp.row_lower_.push_back(lp.row_lower_[iRow]);
1970-
if (row_bound == kIisBoundStatusUpper || row_bound == kIisBoundStatusBoxed)
1971-
iis_lp.row_upper_.push_back(lp.row_upper_[iRow]);
1969+
bound =
1970+
row_bound == kIisBoundStatusLower || row_bound == kIisBoundStatusBoxed
1971+
? lp.row_lower_[iRow]
1972+
: -kHighsInf;
1973+
iis_lp.row_lower_.push_back(bound);
1974+
bound =
1975+
row_bound == kIisBoundStatusUpper || row_bound == kIisBoundStatusBoxed
1976+
? lp.row_upper_[iRow]
1977+
: kHighsInf;
1978+
iis_lp.row_upper_.push_back(bound);
19721979
}
19731980

19741981
for (HighsInt iisCol = 0; iisCol < iis_num_col; iisCol++) {
19751982
HighsInt iCol = this->iis_.col_index_[iisCol];
19761983
iis_lp.col_cost_.push_back(lp.col_cost_[iCol]);
19771984
HighsInt col_bound = this->iis_.col_bound_[iisCol];
1978-
if (col_bound == kIisBoundStatusLower || col_bound == kIisBoundStatusBoxed)
1979-
iis_lp.col_lower_.push_back(lp.col_lower_[iCol]);
1980-
if (col_bound == kIisBoundStatusUpper || col_bound == kIisBoundStatusBoxed)
1981-
iis_lp.col_upper_.push_back(lp.col_upper_[iCol]);
1985+
bound =
1986+
col_bound == kIisBoundStatusLower || col_bound == kIisBoundStatusBoxed
1987+
? lp.col_lower_[iCol]
1988+
: -kHighsInf;
1989+
iis_lp.col_lower_.push_back(bound);
1990+
bound =
1991+
col_bound == kIisBoundStatusUpper || col_bound == kIisBoundStatusBoxed
1992+
? lp.col_upper_[iCol]
1993+
: kHighsInf;
1994+
iis_lp.col_upper_.push_back(bound);
19821995
for (HighsInt iEl = lp.a_matrix_.start_[iCol];
19831996
iEl < lp.a_matrix_.start_[iCol + 1]; iisCol++) {
19841997
HighsInt iRow = lp.a_matrix_.index_[iEl];

0 commit comments

Comments
 (0)