diff --git a/src/Highs.h b/src/Highs.h index 27c5a936b8..275fa36c3b 100644 --- a/src/Highs.h +++ b/src/Highs.h @@ -1515,8 +1515,8 @@ class Highs { HighsStatus getRangingInterface(); HighsStatus computeIisInterface(); - HighsStatus computeInfeasibleRows(const bool elastic_columns = false, - HighsInt* infeasible_row = nullptr); + HighsStatus computeInfeasibleRows(const bool elastic_columns, + std::vector& infeasible_row); HighsStatus extractIis(HighsInt& num_iis_col, HighsInt& num_iis_row, HighsInt* iis_col_index, HighsInt* iis_row_index, HighsInt* iis_col_bound, HighsInt* iis_row_bound); diff --git a/src/lp_data/HighsIis.cpp b/src/lp_data/HighsIis.cpp index 3a428ed97d..efa989430a 100644 --- a/src/lp_data/HighsIis.cpp +++ b/src/lp_data/HighsIis.cpp @@ -150,23 +150,22 @@ bool HighsIis::trivial(const HighsLp& lp, const HighsOptions& options) { HighsStatus HighsIis::getData(const HighsLp& lp, const HighsOptions& options, const HighsBasis& basis, - const double* dual_ray_value) { + const std::vector& infeasible_row) { // Check for trivial IIS should have been done earlier assert(!this->trivial(lp, options)); if (options.iis_strategy == kIisStrategyFromRayRowPriority || options.iis_strategy == kIisStrategyFromRayColPriority) { // Identify the LP corresponding to the ray - std::vector from_row; + std::vector from_row = infeasible_row; std::vector from_col; std::vector to_row; to_row.assign(lp.num_row_, -1); assert(lp.a_matrix_.isColwise()); - for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) { - if (dual_ray_value[iRow]) { - to_row[iRow] = from_row.size(); - from_row.push_back(iRow); - } + for (HighsInt iX = 0; iX < HighsInt(infeasible_row.size()); iX++) { + HighsInt iRow = infeasible_row[iX]; + to_row[iRow] = iX; + from_row.push_back(iRow); } for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) { bool use_col = false; diff --git a/src/lp_data/HighsIis.h b/src/lp_data/HighsIis.h index f9f418c131..72754c8f0f 100644 --- a/src/lp_data/HighsIis.h +++ b/src/lp_data/HighsIis.h @@ -37,7 +37,8 @@ class HighsIis { void removeCol(const HighsInt col); void removeRow(const HighsInt row); HighsStatus getData(const HighsLp& lp, const HighsOptions& options, - const HighsBasis& basis, const double* dual_ray_value); + const HighsBasis& basis, + const std::vector& infeasible_row); HighsStatus compute(const HighsLp& lp, const HighsOptions& options, const HighsBasis* basis = nullptr); diff --git a/src/lp_data/HighsInterface.cpp b/src/lp_data/HighsInterface.cpp index 7ad4b4d12e..d4f6461581 100644 --- a/src/lp_data/HighsInterface.cpp +++ b/src/lp_data/HighsInterface.cpp @@ -1573,7 +1573,7 @@ HighsStatus Highs::computeIisInterface() { } assert(ekk_instance_.status_.has_invert); assert(!lp.is_moved_); - std::vector dual_ray_value; + std::vector infeasible_row; if (options_.iis_strategy == kIisStrategyFromRayRowPriority || options_.iis_strategy == kIisStrategyFromRayColPriority) { const bool has_dual_ray = ekk_instance_.status_.has_dual_ray; @@ -1582,21 +1582,25 @@ HighsStatus Highs::computeIisInterface() { HighsInt iRow = ekk_instance_.info_.dual_ray_row_; rhs.assign(num_row, 0); rhs[iRow] = ekk_instance_.info_.dual_ray_sign_; - dual_ray_value.resize(num_row); + std::vector dual_ray_value(num_row); HighsInt* dual_ray_num_nz = 0; basisSolveInterface(rhs, dual_ray_value.data(), dual_ray_num_nz, NULL, true); + for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) + if (dual_ray_value[iRow]) infeasible_row.push_back(iRow); } else { highsLogUser(options_.log_options, HighsLogType::kError, "No dual ray to start IIS calculation\n"); return HighsStatus::kError; } + } else { + this->computeInfeasibleRows(false, infeasible_row); } - return this->iis_.getData(lp, options_, basis_, dual_ray_value.data()); + return this->iis_.getData(lp, options_, basis_, infeasible_row); } HighsStatus Highs::computeInfeasibleRows(const bool elastic_columns, - HighsInt* infeasible_row) { + std::vector& infeasible_row) { // Elasticity filter // // Construct the e-LP: