Skip to content

Commit d175741

Browse files
committed
Added IisStrategy and IisStatus enums contents to highs_c_api.h
1 parent ab329a0 commit d175741

File tree

7 files changed

+60
-14
lines changed

7 files changed

+60
-14
lines changed

highs/Highs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,7 @@ class Highs {
16621662
HighsStatus getRangingInterface();
16631663

16641664
HighsStatus getIisInterface();
1665+
HighsStatus getIisInterfaceReturn(const HighsStatus return_status);
16651666

16661667
HighsStatus elasticityFilterReturn(
16671668
const HighsStatus return_status, const bool feasible_model,

highs/highs_bindings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,6 +1679,14 @@ PYBIND11_MODULE(_core, m, py::mod_gil_not_used()) {
16791679
.value("kDevex", EdgeWeightMode::kDevex)
16801680
.value("kSteepestEdge", EdgeWeightMode::kSteepestEdge)
16811681
.value("kCount", EdgeWeightMode::kCount);
1682+
1683+
py::module_ iis = m.def_submodule("iis", "IIS interface submodule");
1684+
py::enum_<HighsIisStatus>(iis, "HighsIisStatus",
1685+
py::module_local())
1686+
.value("kIisStatusInConflict", HighsIisStatus::kIisStatusInConflict)
1687+
.value("kIisStatusNotInConflict", HighsIisStatus::kIisStatusNotInConflict)
1688+
.value("kIisStatusMaybeInConflict", HighsIisStatus::kIisStatusMaybeInConflict);
1689+
16821690
py::module_ callbacks = m.def_submodule("cb", "Callback interface submodule");
16831691
// Types for interface
16841692
py::enum_<HighsCallbackType>(callbacks, "HighsCallbackType",

highs/interfaces/highs_c_api.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,14 @@ const char* const kHighsCallbackDataOutCutpoolValueName = "cutpool_value";
133133
const char* const kHighsCallbackDataOutCutpoolLowerName = "cutpool_lower";
134134
const char* const kHighsCallbackDataOutCutpoolUpperName = "cutpool_upper";
135135

136+
const HighsInt kHighsIisStrategyLight = 0;
137+
// const HighsInt kHighsIisStrategyFromLpRowPriority = 1; // WIP
138+
// const HighsInt kHighsIisStrategyFromLpColPriority = 2; // WIP
139+
140+
const HighsInt kHighsIisStatusInConflict = 0;
141+
const HighsInt kHighsIisStatusNotInConflict = 1;
142+
const HighsInt kHighsIisStatusMaybeInConflict = 2;
143+
136144
#ifdef __cplusplus
137145
extern "C" {
138146
#endif

highs/lp_data/HConst.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ enum PresolveRuleType : int {
268268
kPresolveRuleCount,
269269
};
270270

271-
enum IisStrategy {
271+
enum IisStrategy : int {
272272
kIisStrategyMin = 0,
273273
kIisStrategyLight = kIisStrategyMin, // 0
274274
kIisStrategyFromLpRowPriority, // 1
@@ -278,6 +278,14 @@ enum IisStrategy {
278278
kIisStrategyMax = kIisStrategyFromLpColPriority
279279
};
280280

281+
enum IisStatus {
282+
kIisStatusMin = 0,
283+
kIisStatusInConflict = kIisStatusMin, // 0
284+
kIisStatusNotInConflict, // 1
285+
kIisStatusMaybeInConflict, // 2
286+
kIisStatusMax = kIisStatusMaybeInConflict
287+
};
288+
281289
// Default KKT tolerance
282290
const double kDefaultKktTolerance = 1e-7;
283291

highs/lp_data/HighsIis.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ void HighsIis::invalidate() {
2020
this->row_index_.clear();
2121
this->col_bound_.clear();
2222
this->row_bound_.clear();
23+
this->col_status_.clear();
24+
this->row_status_.clear();
2325
this->info_.clear();
2426
this->lp_.clear();
2527
}
@@ -120,8 +122,6 @@ bool HighsIis::trivial(const HighsLp& lp, const HighsOptions& options) {
120122
num_iis_col + num_iis_row < 2);
121123
this->valid_ = true;
122124
this->strategy_ = options.iis_strategy;
123-
// Construct the ISS LP
124-
this->getLp(lp);
125125
return true;
126126
}
127127
// Now look for empty rows that cannot have zero activity
@@ -143,8 +143,6 @@ bool HighsIis::trivial(const HighsLp& lp, const HighsOptions& options) {
143143
if (this->row_index_.size() > 0) {
144144
this->valid_ = true;
145145
this->strategy_ = options.iis_strategy;
146-
// Construct the ISS LP
147-
this->getLp(lp);
148146
return true;
149147
}
150148
}
@@ -280,6 +278,18 @@ void HighsIis::getLp(const HighsLp& lp) {
280278
iis_lp.model_name_ = lp.model_name_ + "_IIS";
281279
}
282280

281+
void HighsIis::getStatus(const HighsLp& lp) {
282+
if (!this->valid_) return;
283+
this->col_status_.assign(lp.num_col_, kIisStatusNotInConflict);
284+
this->row_status_.assign(lp.num_row_, kIisStatusNotInConflict);
285+
HighsInt iis_num_col = this->col_index_.size();
286+
HighsInt iis_num_row = this->row_index_.size();
287+
for (HighsInt iisCol = 0; iisCol < iis_num_col; iisCol++)
288+
this->col_status_[this->col_index_[iisCol]] = kIisStatusInConflict;
289+
for (HighsInt iisRow = 0; iisRow < iis_num_row; iisRow++)
290+
this->row_status_[this->row_index_[iisRow]] = kIisStatusInConflict;
291+
}
292+
283293
HighsStatus HighsIis::compute(const HighsLp& lp, const HighsOptions& options,
284294
const HighsBasis* basis) {
285295
const HighsLogOptions& log_options = options.log_options;

highs/lp_data/HighsIis.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class HighsIis {
4444
const HighsBasis& basis,
4545
const std::vector<HighsInt>& infeasible_row);
4646
void getLp(const HighsLp& lp);
47+
void getStatus(const HighsLp& lp);
4748

4849
HighsStatus compute(const HighsLp& lp, const HighsOptions& options,
4950
const HighsBasis* basis = nullptr);
@@ -59,6 +60,8 @@ class HighsIis {
5960
std::vector<HighsInt> row_index_;
6061
std::vector<HighsInt> col_bound_;
6162
std::vector<HighsInt> row_bound_;
63+
std::vector<HighsInt> col_status_;
64+
std::vector<HighsInt> row_status_;
6265
std::vector<HighsIisInfo> info_;
6366
HighsLp lp_;
6467
};

highs/lp_data/HighsInterface.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,6 +1862,16 @@ HighsStatus Highs::getRangingInterface() {
18621862
return getRangingData(this->ranging_, solver_object);
18631863
}
18641864

1865+
HighsStatus Highs::getIisInterfaceReturn(const HighsStatus return_status) {
1866+
if (return_status != HighsStatus::kError) {
1867+
// Construct the ISS LP
1868+
this->iis_.getLp(model_.lp_);
1869+
// Construct the ISS status vectors
1870+
this->iis_.getStatus(model_.lp_);
1871+
}
1872+
return return_status;
1873+
}
1874+
18651875
HighsStatus Highs::getIisInterface() {
18661876
if (this->model_status_ == HighsModelStatus::kOptimal ||
18671877
this->model_status_ == HighsModelStatus::kUnbounded) {
@@ -1872,7 +1882,7 @@ HighsStatus Highs::getIisInterface() {
18721882
this->iis_.invalidate();
18731883
// No IIS exists, so validate the empty HighsIis instance
18741884
this->iis_.valid_ = true;
1875-
return HighsStatus::kOk;
1885+
return this->getIisInterfaceReturn(HighsStatus::kOk);
18761886
}
18771887
HighsStatus return_status = HighsStatus::kOk;
18781888
if (this->model_status_ != HighsModelStatus::kNotset &&
@@ -1882,30 +1892,30 @@ HighsStatus Highs::getIisInterface() {
18821892
"Calling Highs::getIis for a model with status %s\n",
18831893
this->modelStatusToString(this->model_status_).c_str());
18841894
}
1885-
if (this->iis_.valid_) return HighsStatus::kOk;
1895+
if (this->iis_.valid_) return this->getIisInterfaceReturn(HighsStatus::kOk);
18861896
this->iis_.invalidate();
18871897
const HighsLp& lp = model_.lp_;
18881898
// Check for trivial IIS: empty infeasible row or inconsistent bounds
18891899
if (this->iis_.trivial(lp, options_)) {
18901900
this->model_status_ = HighsModelStatus::kInfeasible;
1891-
return HighsStatus::kOk;
1901+
return this->getIisInterfaceReturn(HighsStatus::kOk);
18921902
}
18931903
HighsInt num_row = lp.num_row_;
18941904
if (num_row == 0) {
18951905
// For an LP with no rows, the only scope for infeasibility is
18961906
// inconsistent columns bounds - which has already been assessed,
18971907
// so validate the empty HighsIis instance
18981908
this->iis_.valid_ = true;
1899-
return HighsStatus::kOk;
1909+
return this->getIisInterfaceReturn(HighsStatus::kOk);
19001910
}
19011911
// Look for infeasible rows based on row value bounds
19021912
if (this->iis_.rowValueBounds(lp, options_)) {
19031913
this->model_status_ = HighsModelStatus::kInfeasible;
1904-
return HighsStatus::kOk;
1914+
return this->getIisInterfaceReturn(HighsStatus::kOk);
19051915
}
19061916
// Don't continue with more expensive techniques if using the IIS
19071917
// light strategy
1908-
if (options_.iis_strategy == kIisStrategyLight) return HighsStatus::kOk;
1918+
if (options_.iis_strategy == kIisStrategyLight) return this->getIisInterfaceReturn(HighsStatus::kOk);
19091919
const bool ray_option = false;
19101920
// options_.iis_strategy == kIisStrategyFromRayRowPriority ||
19111921
// options_.iis_strategy == kIisStrategyFromRayColPriority;
@@ -2015,9 +2025,7 @@ HighsStatus Highs::getIisInterface() {
20152025
int(max_iterations), min_time,
20162026
num_lp_solved > 0 ? sum_time / num_lp_solved : 0, max_time);
20172027
}
2018-
// Construct the ISS LP
2019-
this->iis_.getLp(lp);
2020-
return return_status;
2028+
return this->getIisInterfaceReturn(return_status);
20212029
}
20222030

20232031
HighsStatus Highs::elasticityFilterReturn(

0 commit comments

Comments
 (0)