Skip to content

Commit

Permalink
Introduced simplex_stats_ and presolved_lp_simplex_stats_ into Highs.h
Browse files Browse the repository at this point in the history
  • Loading branch information
jajhall committed Nov 29, 2024
1 parent 258e8c0 commit 17c4c8a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
36 changes: 29 additions & 7 deletions check/TestLpSolvers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,23 +648,45 @@ TEST_CASE("simplex-stats", "[highs_lp_solver]") {

Highs h;
const HighsSimplexStats& simplex_stats = h.getSimplexStats();
const HighsSimplexStats& presolved_lp_simplex_stats =
h.getPresolvedLpSimplexStats();
h.setOptionValue("output_flag", dev_run);
// std::string model = "dcp2";
std::string model = "adlittle";
std::string model_file =
std::string(HIGHS_DIR) + "/check/instances/adlittle.mps";
std::string(HIGHS_DIR) + "/check/instances/" + model + ".mps";
REQUIRE(h.readModel(model_file) == HighsStatus::kOk);

REQUIRE(h.run() == HighsStatus::kOk);
REQUIRE(simplex_stats.valid);
REQUIRE(simplex_stats.iteration_count == 0);
REQUIRE(simplex_stats.num_invert == 1);
REQUIRE(simplex_stats.iteration_count >= 0);
REQUIRE(simplex_stats.num_invert > 0);
REQUIRE(simplex_stats.last_invert_num_el > 0);
REQUIRE(simplex_stats.last_factored_basis_num_el > 0);
REQUIRE(simplex_stats.col_aq_density == 0);
REQUIRE(simplex_stats.row_ep_density == 0);
REQUIRE(simplex_stats.row_ap_density == 0);
REQUIRE(simplex_stats.row_DSE_density == 0);
if (simplex_stats.iteration_count > 0) {
REQUIRE(simplex_stats.col_aq_density > 0);
REQUIRE(simplex_stats.row_ep_density > 0);
REQUIRE(simplex_stats.row_ap_density > 0);
REQUIRE(simplex_stats.row_DSE_density > 0);
} else {
REQUIRE(simplex_stats.col_aq_density == 0);
REQUIRE(simplex_stats.row_ep_density == 0);
REQUIRE(simplex_stats.row_ap_density == 0);
REQUIRE(simplex_stats.row_DSE_density == 0);
}
if (dev_run) h.reportSimplexStats(stdout);

REQUIRE(presolved_lp_simplex_stats.valid);
REQUIRE(presolved_lp_simplex_stats.iteration_count > 0);
REQUIRE(presolved_lp_simplex_stats.num_invert > 0);
REQUIRE(presolved_lp_simplex_stats.last_invert_num_el > 0);
REQUIRE(presolved_lp_simplex_stats.last_factored_basis_num_el > 0);
REQUIRE(presolved_lp_simplex_stats.col_aq_density > 0);
REQUIRE(presolved_lp_simplex_stats.row_ep_density > 0);
REQUIRE(presolved_lp_simplex_stats.row_ap_density > 0);
REQUIRE(presolved_lp_simplex_stats.row_DSE_density > 0);
if (dev_run) h.reportPresolvedLpSimplexStats(stdout);

h.clearSolver();
h.setOptionValue("presolve", kHighsOffString);
REQUIRE(h.run() == HighsStatus::kOk);
Expand Down
13 changes: 10 additions & 3 deletions src/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1216,11 +1216,16 @@ class Highs {

// Start of advanced methods for HiGHS MIP solver

const HighsSimplexStats& getSimplexStats() const {
return ekk_instance_.getSimplexStats();
const HighsSimplexStats& getPresolvedLpSimplexStats() const {
return presolved_lp_simplex_stats_;
}
void reportPresolvedLpSimplexStats(FILE* file) const {
presolved_lp_simplex_stats_.report(file, "Presolved LP");
}

const HighsSimplexStats& getSimplexStats() const { return simplex_stats_; }
void reportSimplexStats(FILE* file) const {
ekk_instance_.reportSimplexStats(file);
simplex_stats_.report(file, "Original LP");
}

/**
Expand Down Expand Up @@ -1438,6 +1443,8 @@ class Highs {
HighsSparseMatrix standard_form_matrix_;

HEkk ekk_instance_;
HighsSimplexStats simplex_stats_;
HighsSimplexStats presolved_lp_simplex_stats_;

HighsPresolveLog presolve_log_;

Expand Down
7 changes: 7 additions & 0 deletions src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,6 +1275,7 @@ HighsStatus Highs::solve() {
solveLp(incumbent_lp,
"Solving LP without presolve, or with basis, or unconstrained",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
if (return_status == HighsStatus::kError)
Expand Down Expand Up @@ -1318,6 +1319,7 @@ HighsStatus Highs::solve() {
ekk_instance_.lp_name_ = "Original LP";
solveLp(incumbent_lp, "Not presolved: solving the LP",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
if (return_status == HighsStatus::kError)
Expand All @@ -1330,6 +1332,7 @@ HighsStatus Highs::solve() {
reportPresolveReductions(log_options, incumbent_lp, false);
solveLp(incumbent_lp, "Problem not reduced by presolve: solving the LP",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
if (return_status == HighsStatus::kError)
Expand Down Expand Up @@ -1378,6 +1381,7 @@ HighsStatus Highs::solve() {
options_.objective_bound = kHighsInf;
solveLp(reduced_lp, "Solving the presolved LP",
this_solve_presolved_lp_time);
presolved_lp_simplex_stats_ = this->ekk_instance_.getSimplexStats();
if (ekk_instance_.status_.initialised_for_solve) {
// Record the pivot threshold resulting from solving the presolved LP
// with simplex
Expand Down Expand Up @@ -1442,6 +1446,7 @@ HighsStatus Highs::solve() {
"Solving the original LP with primal simplex "
"to determine infeasible or unbounded",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
// Recover the options
options_ = save_options;
if (return_status == HighsStatus::kError)
Expand Down Expand Up @@ -1579,6 +1584,7 @@ HighsStatus Highs::solve() {
solveLp(incumbent_lp,
"Solving the original LP from the solution after postsolve",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
// Determine the iteration count
postsolve_iteration_count += info_.simplex_iteration_count;
return_status =
Expand Down Expand Up @@ -4191,6 +4197,7 @@ HighsStatus Highs::callRunPostsolve(const HighsSolution& solution,
"Solving the original LP from the solution after postsolve");
// Determine the timing record
timer_.stop(timer_.solve_clock);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
// Recover the options
Expand Down

0 comments on commit 17c4c8a

Please sign in to comment.