| 251 | } |
| 252 | |
| 253 | void testBasisRestart(Highs& highs, const std::string& basis_file, |
| 254 | const bool from_file) { |
| 255 | // Checks that no simplex iterations are required if a saved optimal |
| 256 | // basis is used for the original LP after changing a bound, solving |
| 257 | // - so that the internal basis changes - and then restoring the |
| 258 | // original LP |
| 259 | HighsStatus return_status; |
| 260 | // highs.writeSolution("", kSolutionStylePretty); |
| 261 | // Change a bound and resolve |
| 262 | |
| 263 | const HighsLp& lp = highs.getLp(); |
| 264 | const HighsBasis& basis = highs.getBasis(); |
| 265 | const HighsSolution& solution = highs.getSolution(); |
| 266 | const HighsInfo& info = highs.getInfo(); |
| 267 | // Find the first basic variable |
| 268 | HighsInt iCol; |
| 269 | for (iCol = 0; iCol < lp.num_col_; iCol++) { |
| 270 | if (basis.col_status[iCol] == HighsBasisStatus::kBasic) break; |
| 271 | } |
| 272 | assert(iCol < lp.num_col_); |
| 273 | const HighsInt changeCol = iCol; |
| 274 | const double old_lower_bound = lp.col_lower_[changeCol]; |
| 275 | const double old_upper_bound = lp.col_upper_[changeCol]; |
| 276 | const double new_lower_bound = solution.col_value[changeCol] + 0.1; |
| 277 | highs.changeColBounds(changeCol, new_lower_bound, old_upper_bound); |
| 278 | |
| 279 | return_status = highs.run(); |
| 280 | |
| 281 | if (dev_run) { |
| 282 | printf("After modifying lower bound of column %" HIGHSINT_FORMAT |
| 283 | " from %g to %g, solving the " |
| 284 | "LP " |
| 285 | "requires %" HIGHSINT_FORMAT " iterations and objective is %g\n", |
| 286 | changeCol, old_lower_bound, new_lower_bound, |
| 287 | info.simplex_iteration_count, highs.getObjectiveValue()); |
| 288 | // highs.writeSolution("", kSolutionStylePretty); |
| 289 | } |
| 290 | // Make sure that the test requires iterations |
| 291 | assert(info.simplex_iteration_count > 0); |
| 292 | |
| 293 | // Recover bound, load optimal basis and resolve |
| 294 | |
| 295 | highs.changeColBounds(changeCol, old_lower_bound, old_upper_bound); |
| 296 | |
| 297 | if (from_file) { |
| 298 | return_status = highs.readBasis(basis_file); |
| 299 | } else { |
| 300 | return_status = highs.setBasis(basis_data); |
| 301 | } |
| 302 | REQUIRE(return_status == HighsStatus::kOk); |
| 303 | |
| 304 | return_status = highs.run(); |
| 305 | REQUIRE(return_status == HighsStatus::kOk); |
| 306 | |
| 307 | if (dev_run) { |
| 308 | printf("After restoring lower bound of column %" HIGHSINT_FORMAT |
| 309 | " from %g to %g, solving the " |
| 310 | "LP " |
no test coverage detected