Skip to content

Commit eab8b22

Browse files
committed
Form IIS LP with IIS, and hold it as a member of HighsIis
1 parent 81fcd9d commit eab8b22

File tree

4 files changed

+183
-182
lines changed

4 files changed

+183
-182
lines changed

check/TestIis.cpp

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "Highs.h"
66
#include "catch.hpp"
77

8-
const bool dev_run = true; // false;
8+
const bool dev_run = true; // false; //
99
const double inf = kHighsInf;
1010

1111
void testIis(const std::string& model, const HighsIis& iis);
@@ -51,6 +51,11 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
5151
HighsIis iis;
5252
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
5353
checkIisLp(lp, iis, iis_lp);
54+
55+
highs.passModel(lp);
56+
highs.getIis(iis);
57+
REQUIRE(highs.checkIis() == HighsStatus::kOk);
58+
5459
// Perform full IIS
5560
REQUIRE(highs.run() == HighsStatus::kOk);
5661
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
@@ -117,11 +122,16 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
117122

118123
checkIisLp(lp, iis, iis_lp);
119124

125+
highs.passModel(lp);
126+
highs.getIis(iis);
127+
REQUIRE(highs.checkIis() == HighsStatus::kOk);
128+
120129
highs.resetGlobalScheduler(true);
121130
}
122131

123132
TEST_CASE("lp-get-iis-light", "[iis]") {
124133
HighsLp lp;
134+
lp.model_name_ = "lp-get-iis-light";
125135
lp.num_col_ = 4;
126136
lp.num_row_ = 3;
127137
lp.col_cost_ = {0, 0, 0, 0};
@@ -135,7 +145,14 @@ TEST_CASE("lp-get-iis-light", "[iis]") {
135145
lp.a_matrix_.start_ = {0, 3, 7, 10};
136146
lp.a_matrix_.index_ = { 0, 1, 2, 0, 1, 2, 3, 1, 2, 3};
137147
lp.a_matrix_.value_ = {1.5, 2, 1, 4, -2, 1, 2, -2, -1.5, -1};
138-
Highs highs;
148+
//
149+
// 1.5w + 2x + y <= 30
150+
//
151+
// -10 <= 4w -2x + y + 2z <= 15
152+
//
153+
// -2x -1.5y -z >= -34
154+
//
155+
Highs highs;
139156
highs.setOptionValue("output_flag", dev_run);
140157
highs.passModel(lp);
141158
highs.setOptionValue("iis_strategy", kIisStrategyLight);
@@ -193,6 +210,15 @@ TEST_CASE("lp-get-iis", "[iis]") {
193210
lp.a_matrix_.start_ = {0, 2, 4, 6};
194211
lp.a_matrix_.index_ = {0, 1, 0, 1, 0, 1};
195212
lp.a_matrix_.value_ = {2, 1, 1, 3, 1, 1};
213+
//
214+
// 2x + y <= 8
215+
//
216+
// x + 3y <= 9
217+
//
218+
// x + y <= -2
219+
//
220+
// x, y \in [0, inf)
221+
//
196222
// lp.col_name_ = {"Col0", "Col1"};
197223
// lp.row_name_ = {"Row0", "Row1", "Row2"};
198224
Highs highs;
@@ -213,6 +239,10 @@ TEST_CASE("lp-get-iis", "[iis]") {
213239
REQUIRE(highs.getIisLp(iis_lp) == HighsStatus::kOk);
214240
checkIisLp(lp, iis, iis_lp);
215241

242+
highs.passModel(lp);
243+
highs.getIis(iis);
244+
REQUIRE(highs.checkIis() == HighsStatus::kOk);
245+
216246
highs.resetGlobalScheduler(true);
217247
}
218248

@@ -555,6 +585,10 @@ void testMps(std::string& model, const HighsInt iis_strategy,
555585

556586
checkIisLp(lp, iis, iis_lp);
557587

588+
highs.passModel(lp);
589+
highs.getIis(iis);
590+
REQUIRE(highs.checkIis() == HighsStatus::kOk);
591+
558592
} else {
559593
REQUIRE(num_iis_col == 0);
560594
REQUIRE(num_iis_row == 0);
@@ -588,7 +622,6 @@ void checkIisLp(HighsLp& lp, const HighsIis& iis, const HighsLp& iis_lp) {
588622
double bound;
589623
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++) {
590624
HighsInt iRow = iis.row_index_[iisRow];
591-
printf("checkIisLp: iRow = %d\n", int(iRow));
592625
if (iRow < 0 || iRow >= lp.num_row_) {
593626
printf("iRow out of range\n");
594627
}
@@ -648,14 +681,14 @@ void checkIisLp(HighsLp& lp, const HighsIis& iis, const HighsLp& iis_lp) {
648681
HighsInt iisRow = iis_row[iRow];
649682
if (iisRow >= 0) {
650683
const bool index_ok = index[iisRow] == iRow;
651-
if (!index_ok) {
684+
if (!index_ok && dev_run) {
652685
printf("checkIisLp: IIS LP matrix index incorrect %d != %d\n",
653686
int(index[iisRow]), int(iRow));
654687
}
655688
REQUIRE(index_ok);
656689
index[iisRow] = illegal_index;
657690
const bool value_ok = value[iisRow] == lp.a_matrix_.value_[iEl];
658-
if (!value_ok) {
691+
if (!value_ok && dev_run) {
659692
printf("checkIisLp: IIS LP matrix value incorrect %g != %g\n",
660693
value[iisRow], lp.a_matrix_.value_[iEl]);
661694
}
@@ -683,13 +716,13 @@ void checkIisLp(HighsLp& lp, const HighsIis& iis, const HighsLp& iis_lp) {
683716
HighsInt iisRow = iis_lp.a_matrix_.index_[iEl];
684717
HighsInt iRow = iis.row_index_[iisRow];
685718
const bool index_ok = index[iRow] == iisRow;
686-
if (!index_ok) {
719+
if (!index_ok && dev_run) {
687720
printf("checkIisLp: IIS LP matrix index incorrect %d != %d\n",
688721
int(index[iRow]), int(iisRow));
689722
}
690723
REQUIRE(index_ok);
691724
const bool value_ok = value[iRow] == iis_lp.a_matrix_.value_[iEl];
692-
if (!value_ok) {
725+
if (!value_ok && dev_run) {
693726
printf("checkIisLp: IIS LP matrix value incorrect %g != %g\n",
694727
value[iRow], iis_lp.a_matrix_.value_[iEl]);
695728
}

highs/lp_data/Highs.cpp

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,67 +1962,9 @@ HighsStatus Highs::getIisLp(HighsLp& iis_lp) {
19621962
return_status, "getIisInterface");
19631963
if (return_status == HighsStatus::kError) return return_status;
19641964
}
1965-
iis_lp.clear();
1966-
HighsInt iis_num_col = this->iis_.col_index_.size();
1967-
HighsInt iis_num_row = this->iis_.row_index_.size();
1968-
HighsLp& lp = this->model_.lp_;
1969-
lp.a_matrix_.ensureColwise();
1970-
// Scatter the IIS rows into a full-length vector to identify IIS
1971-
// rows with LP rows
1972-
std::vector<HighsInt> iis_row;
1973-
iis_row.assign(lp.num_row_, -1);
1974-
double bound;
1975-
const bool has_row_name = lp.row_names_.size() > 0;
1976-
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++) {
1977-
HighsInt iRow = this->iis_.row_index_[iisRow];
1978-
iis_row[iRow] = iisRow;
1979-
if (has_row_name) iis_lp.row_names_.push_back(lp.row_names_[iRow]);
1980-
HighsInt row_bound = this->iis_.row_bound_[iisRow];
1981-
bound =
1982-
row_bound == kIisBoundStatusLower || row_bound == kIisBoundStatusBoxed
1983-
? lp.row_lower_[iRow]
1984-
: -kHighsInf;
1985-
iis_lp.row_lower_.push_back(bound);
1986-
bound =
1987-
row_bound == kIisBoundStatusUpper || row_bound == kIisBoundStatusBoxed
1988-
? lp.row_upper_[iRow]
1989-
: kHighsInf;
1990-
iis_lp.row_upper_.push_back(bound);
1991-
}
1992-
1993-
const bool has_col_name = lp.col_names_.size() > 0;
1994-
for (HighsInt iisCol = 0; iisCol < iis_num_col; iisCol++) {
1995-
HighsInt iCol = this->iis_.col_index_[iisCol];
1996-
iis_lp.col_cost_.push_back(lp.col_cost_[iCol]);
1997-
if (has_col_name) iis_lp.col_names_.push_back(lp.col_names_[iCol]);
1998-
HighsInt col_bound = this->iis_.col_bound_[iisCol];
1999-
bound =
2000-
col_bound == kIisBoundStatusLower || col_bound == kIisBoundStatusBoxed
2001-
? lp.col_lower_[iCol]
2002-
: -kHighsInf;
2003-
iis_lp.col_lower_.push_back(bound);
2004-
bound =
2005-
col_bound == kIisBoundStatusUpper || col_bound == kIisBoundStatusBoxed
2006-
? lp.col_upper_[iCol]
2007-
: kHighsInf;
2008-
iis_lp.col_upper_.push_back(bound);
2009-
for (HighsInt iEl = lp.a_matrix_.start_[iCol];
2010-
iEl < lp.a_matrix_.start_[iCol + 1]; iEl++) {
2011-
HighsInt iRow = lp.a_matrix_.index_[iEl];
2012-
HighsInt iisRow = iis_row[iRow];
2013-
if (iisRow >= 0) {
2014-
iis_lp.a_matrix_.index_.push_back(iisRow);
2015-
iis_lp.a_matrix_.value_.push_back(lp.a_matrix_.value_[iEl]);
2016-
}
2017-
}
2018-
iis_lp.a_matrix_.start_.push_back(iis_lp.a_matrix_.index_.size());
2019-
}
2020-
iis_lp.num_col_ = iis_lp.col_cost_.size();
2021-
iis_lp.num_row_ = iis_lp.row_lower_.size();
2022-
iis_lp.a_matrix_.num_col_ = iis_lp.num_col_;
2023-
iis_lp.a_matrix_.num_row_ = iis_lp.num_row_;
2024-
iis_lp.model_name_ = lp.model_name_ + "_IIS";
2025-
return return_status;
1965+
this->model_.lp_.a_matrix_.ensureColwise();
1966+
this->iis_.getLp(this->model_.lp_, iis_lp);
1967+
return HighsStatus::kOk;
20261968
}
20271969

20281970
HighsStatus Highs::getDualObjectiveValue(

0 commit comments

Comments
 (0)