Skip to content

Commit 8bb529c

Browse files
committed
bin/unit_tests passes; now to clean up use of feasible_model
1 parent 7306852 commit 8bb529c

File tree

4 files changed

+94
-86
lines changed

4 files changed

+94
-86
lines changed

check/TestIis.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
5252
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
5353
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
5454
REQUIRE(iis.valid_ == true);
55-
REQUIRE(iis.irreducible_ == true);
55+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
5656

5757
// Perform full IIS
5858
REQUIRE(highs.run() == HighsStatus::kOk);
@@ -62,7 +62,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
6262
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
6363
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
6464
REQUIRE(iis.valid_ == true);
65-
REQUIRE(iis.irreducible_ == true);
65+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
6666
REQUIRE(iis.col_index_.size() == 0);
6767
REQUIRE(iis.row_index_.size() == 1);
6868
REQUIRE(iis.row_index_[0] == 0);
@@ -81,7 +81,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
8181
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
8282
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
8383
REQUIRE(iis.valid_ == true);
84-
REQUIRE(iis.irreducible_ == true);
84+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
8585
REQUIRE(iis.col_index_.size() == 1);
8686
REQUIRE(iis.row_index_.size() == 0);
8787
REQUIRE(iis.col_index_[0] == 2);
@@ -112,7 +112,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
112112
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
113113
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
114114
REQUIRE(iis.valid_ == true);
115-
REQUIRE(iis.irreducible_ == true);
115+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
116116
REQUIRE(iis.col_index_.size() == 0);
117117
REQUIRE(iis.row_index_.size() == 1);
118118
REQUIRE(iis.row_index_[0] == 0);
@@ -131,7 +131,7 @@ TEST_CASE("lp-incompatible-bounds", "[iis]") {
131131
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
132132
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
133133
REQUIRE(iis.valid_ == true);
134-
REQUIRE(iis.irreducible_ == true);
134+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
135135
REQUIRE(iis.col_index_.size() == 1);
136136
REQUIRE(iis.row_index_.size() == 0);
137137
REQUIRE(iis.col_index_[0] == 0);
@@ -173,7 +173,7 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
173173
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
174174
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
175175
REQUIRE(iis.valid_ == true);
176-
REQUIRE(iis.irreducible_ == true);
176+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
177177
if (dev_run && write_model) {
178178
highs.writeModel("");
179179
highs.writeIisModel("");
@@ -203,7 +203,7 @@ TEST_CASE("lp-empty-infeasible-row", "[iis]") {
203203
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
204204
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
205205
REQUIRE(iis.valid_ == true);
206-
REQUIRE(iis.irreducible_ == true);
206+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
207207
REQUIRE(iis.col_index_.size() == 0);
208208
REQUIRE(iis.row_index_.size() == 1);
209209
REQUIRE(iis.row_index_[0] == empty_row);
@@ -257,7 +257,7 @@ TEST_CASE("lp-get-iis-light", "[iis]") {
257257
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
258258
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
259259
REQUIRE(iis.valid_ == true);
260-
REQUIRE(iis.irreducible_ == true);
260+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
261261
REQUIRE(iis.row_index_.size() == 1);
262262
HighsInt iis_row = iis.row_index_[0];
263263
if (lp.a_matrix_.isColwise()) {
@@ -347,7 +347,7 @@ TEST_CASE("lp-get-iis", "[iis]") {
347347
REQUIRE(highs.getIis(iis) == HighsStatus::kOk);
348348
REQUIRE(highs.getModelStatus() == HighsModelStatus::kInfeasible);
349349
REQUIRE(iis.valid_ == true);
350-
REQUIRE(iis.irreducible_ == true);
350+
REQUIRE(iis.status_ == kIisModelStatusIrreducible);
351351
REQUIRE(iis.col_index_.size() == 2);
352352
REQUIRE(iis.row_index_.size() == 1);
353353
REQUIRE(iis.col_index_[0] == 0);
@@ -612,13 +612,15 @@ void testMps(std::string& model, const HighsInt iis_strategy,
612612
int(num_iis_col), int(num_iis_row));
613613
REQUIRE(iis.valid_ == true);
614614
const bool find_irreducible = kIisStrategyIrreducible & iis_strategy;
615-
if (find_irreducible) REQUIRE(iis.irreducible_);
616-
const HighsInt iis_status =
617-
iis.irreducible_ ? kIisStatusInConflict : kIisStatusMaybeInConflict;
615+
if (find_irreducible) REQUIRE(iis.status_ == kIisModelStatusIrreducible);
616+
const HighsInt in_iis_status =
617+
iis.status_ == kIisModelStatusIrreducible ?
618+
kIisStatusInConflict :
619+
kIisStatusMaybeInConflict;
618620
for (HighsInt iX = 0; iX < num_iis_col; iX++)
619-
REQUIRE(iis.col_status_[iis.col_index_[iX]] == iis_status);
621+
REQUIRE(iis.col_status_[iis.col_index_[iX]] == in_iis_status);
620622
for (HighsInt iX = 0; iX < num_iis_row; iX++)
621-
REQUIRE(iis.row_status_[iis.row_index_[iX]] == iis_status);
623+
REQUIRE(iis.row_status_[iis.row_index_[iX]] == in_iis_status);
622624
} else {
623625
REQUIRE(num_iis_col == 0);
624626
REQUIRE(num_iis_row == 0);
@@ -657,7 +659,7 @@ TEST_CASE("feasible-lp-iis", "[iis]") {
657659
lp.a_matrix_.index_ = {0, 1, 0, 1};
658660
lp.a_matrix_.value_ = {1, 1, 2, 4};
659661
Highs h;
660-
// h.setOptionValue("output_flag", dev_run);
662+
h.setOptionValue("output_flag", dev_run);
661663
h.passModel(lp);
662664
HighsIis iis;
663665
// With kIisStrategyLight, feasibility of the LP is not determined

highs/lp_data/HighsIis.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
void HighsIis::clear() {
1515
this->valid_ = false;
16-
this->irreducible_ = false;
16+
this->status_ = kIisModelStatusUnknown;
1717
this->strategy_ = kIisStrategyMin;
1818
this->col_index_.clear();
1919
this->row_index_.clear();
@@ -123,7 +123,7 @@ bool HighsIis::trivial(const HighsLp& lp, const HighsOptions& options) {
123123
// Should have found exactly 1
124124
assert(num_iis_col + num_iis_row == 1);
125125
this->valid_ = true;
126-
this->irreducible_ = true;
126+
this->status_ = kIisModelStatusIrreducible;
127127
this->strategy_ = options.iis_strategy;
128128
return true;
129129
}
@@ -153,7 +153,7 @@ bool HighsIis::trivial(const HighsLp& lp, const HighsOptions& options) {
153153
if (this->row_index_.size() > 0) {
154154
// If one is found then we've found an IIS
155155
this->valid_ = true;
156-
this->irreducible_ = true;
156+
this->status_ = kIisModelStatusIrreducible;
157157
this->strategy_ = options.iis_strategy;
158158
return true;
159159
}
@@ -228,6 +228,7 @@ bool HighsIis::rowValueBounds(const HighsLp& lp, const HighsOptions& options) {
228228
// Nothing found, but IIS data still valid
229229
this->clear();
230230
this->valid_ = true;
231+
this->status_ = kIisModelStatusUnknown;
231232
this->strategy_ = options.iis_strategy;
232233
return false;
233234
}
@@ -295,7 +296,7 @@ bool HighsIis::rowValueBounds(const HighsLp& lp, const HighsOptions& options) {
295296
assert(this->col_index_.size() == this->col_bound_.size());
296297
assert(this->row_index_.size() == this->row_bound_.size());
297298
this->valid_ = true;
298-
this->irreducible_ = true;
299+
this->status_ = kIisModelStatusIrreducible;
299300
this->strategy_ = options.iis_strategy;
300301
return true;
301302
}
@@ -469,14 +470,13 @@ void HighsIis::setLp(const HighsLp& lp) {
469470
iis_lp.model_name_ = lp.model_name_ + "_IIS";
470471
}
471472

472-
HighsInt HighsIis::nonIsStatus(const HighsModelStatus& model_status) const {
473-
const bool is_feasible =
474-
model_status == HighsModelStatus::kOptimal ||
475-
model_status == HighsModelStatus::kUnbounded;
473+
HighsInt HighsIis::nonIsStatus() const {
474+
const bool is_feasible = this->status_ == kIisModelStatusFeasible;
476475
const bool has_is = this->col_index_.size() || this->row_index_.size();
477476
// If the model is known to be feasible, then there should be no IS,
478477
// and all columns and rows are kIisStatusNotInConflict
479478
if (is_feasible) assert(!has_is);
479+
if (has_is) assert(this->status_ >= kIisModelStatusReducible);
480480
// If there is an IS, then all columns and rows not in the IS are
481481
// kIisStatusNotInConflict
482482
const HighsInt default_iis_status = is_feasible || has_is ?
@@ -485,20 +485,21 @@ HighsInt HighsIis::nonIsStatus(const HighsModelStatus& model_status) const {
485485
return default_iis_status;
486486
}
487487

488-
void HighsIis::setStatus(const HighsLp& lp,
489-
const HighsModelStatus& model_status) {
488+
void HighsIis::setStatus(const HighsLp& lp) {
490489
if (!this->valid_) return;
491-
const HighsInt non_is_status = nonIsStatus(model_status);
490+
const HighsInt non_is_status = nonIsStatus();
491+
const HighsInt in_is_status =
492+
this->status_ == kIisModelStatusIrreducible ?
493+
kIisStatusInConflict :
494+
kIisStatusMaybeInConflict;
492495
this->col_status_.assign(lp.num_col_, non_is_status);
493496
this->row_status_.assign(lp.num_row_, non_is_status);
494-
HighsInt iis_num_col = this->col_index_.size();
495-
HighsInt iis_num_row = this->row_index_.size();
497+
const HighsInt iis_num_col = this->col_index_.size();
498+
const HighsInt iis_num_row = this->row_index_.size();
496499
for (HighsInt iisCol = 0; iisCol < iis_num_col; iisCol++)
497-
this->col_status_[this->col_index_[iisCol]] =
498-
this->irreducible_ ? kIisStatusInConflict : kIisStatusMaybeInConflict;
500+
this->col_status_[this->col_index_[iisCol]] = in_is_status;
499501
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++)
500-
this->row_status_[this->row_index_[iisRow]] =
501-
this->irreducible_ ? kIisStatusInConflict : kIisStatusMaybeInConflict;
502+
this->row_status_[this->row_index_[iisRow]] = in_is_status;
502503
}
503504

504505
HighsStatus HighsIis::compute(const HighsLp& lp, const HighsOptions& options,
@@ -815,20 +816,19 @@ HighsStatus HighsIis::compute(const HighsLp& lp, const HighsOptions& options,
815816
iss_num_row++;
816817
}
817818
}
819+
this->valid_ = true;
820+
this->status_ = kIisModelStatusIrreducible;
821+
this->strategy_ = options.iis_strategy;
818822
this->col_index_.resize(iss_num_col);
819823
this->col_bound_.resize(iss_num_col);
820824
this->row_index_.resize(iss_num_row);
821825
this->row_bound_.resize(iss_num_row);
822-
this->valid_ = true;
823-
this->irreducible_ = true;
824-
this->strategy_ = options.iis_strategy;
825826
return HighsStatus::kOk;
826827
}
827828

828829
bool indexStatusOkReturn(const bool return_value) { return return_value; }
829830

830-
bool HighsIis::indexStatusOk(const HighsLp& lp,
831-
const HighsModelStatus& model_status) const {
831+
bool HighsIis::indexStatusOk(const HighsLp& lp) const {
832832
HighsInt num_col = lp.num_col_;
833833
HighsInt num_row = lp.num_row_;
834834
bool col_status_size_ok =
@@ -877,7 +877,7 @@ bool HighsIis::indexStatusOk(const HighsLp& lp,
877877
return indexStatusOkReturn(false);
878878
row_status[iRow] = illegal_status;
879879
}
880-
const HighsInt non_is_status = nonIsStatus(model_status);
880+
const HighsInt non_is_status = nonIsStatus();
881881
for (HighsInt iCol = 0; iCol < num_col; iCol++) {
882882
if (col_status[iCol] > illegal_status &&
883883
col_status[iCol] != non_is_status)
@@ -1077,7 +1077,7 @@ bool HighsIis::lpOk(const HighsOptions& options) const {
10771077
"HighsIis: IIS LP is not infeasible\n");
10781078
return lpOkReturn(false);
10791079
}
1080-
if (!this->irreducible_) return lpOkReturn(true);
1080+
if (!(this->status_ == kIisModelStatusIrreducible)) return lpOkReturn(true);
10811081
auto optimal = [&]() -> bool {
10821082
if (options.log_dev_level > 0) h.writeModel("");
10831083
h.run();

highs/lp_data/HighsIis.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
#include "model/HighsModel.h"
1515

16-
const bool kIisDevReport = true; // false;
16+
const bool kIisDevReport = false;
1717

1818
enum IisBoundStatus {
1919
kIisBoundStatusDropped = -1,
@@ -24,6 +24,14 @@ enum IisBoundStatus {
2424
kIisBoundStatusBoxed // 4
2525
};
2626

27+
enum IisModelStatus {
28+
kIisModelStatusFeasible = -1,
29+
kIisModelStatusUnknown, // 0
30+
kIisModelStatusInfeasible, // 1
31+
kIisModelStatusReducible, // 2
32+
kIisModelStatusIrreducible // 3
33+
};
34+
2735
struct HighsIisInfo {
2836
double simplex_time = 0;
2937
HighsInt simplex_iterations = 0;
@@ -44,24 +52,22 @@ class HighsIis {
4452
HighsStatus deduce(const HighsLp& lp, const HighsOptions& options,
4553
const HighsBasis& basis);
4654
void setLp(const HighsLp& lp);
47-
HighsInt nonIsStatus(const HighsModelStatus& model_status) const;
48-
void setStatus(const HighsLp& lp,
49-
const HighsModelStatus& model_status);
55+
HighsInt nonIsStatus() const;
56+
void setStatus(const HighsLp& lp);
5057

5158
HighsStatus compute(const HighsLp& lp, const HighsOptions& options,
5259
const HighsBasis* basis = nullptr);
5360

5461
bool trivial(const HighsLp& lp, const HighsOptions& options);
5562
bool rowValueBounds(const HighsLp& lp, const HighsOptions& options);
5663

57-
bool indexStatusOk(const HighsLp& lp,
58-
const HighsModelStatus& model_status) const;
64+
bool indexStatusOk(const HighsLp& lp) const;
5965
bool lpDataOk(const HighsLp& lp, const HighsOptions& options) const;
6066
bool lpOk(const HighsOptions& options) const;
6167

6268
// Data members
6369
bool valid_ = false;
64-
bool irreducible_ = false;
70+
HighsInt status_;
6571
HighsInt strategy_ = kIisStrategyMin;
6672
std::vector<HighsInt> col_index_;
6773
std::vector<HighsInt> row_index_;

0 commit comments

Comments
 (0)