From 258e8c063e6c517244ac3cad15f814d2494856ac Mon Sep 17 00:00:00 2001 From: JAJHall Date: Thu, 28 Nov 2024 17:00:06 +0000 Subject: [PATCH] HighsSimplexStats struct gives data about last simplex solve --- check/TestLpSolvers.cpp | 42 ++++++++++++++++++++++++++++++----------- src/Highs.h | 8 ++++++-- src/lp_data/HStruct.h | 5 ++--- src/simplex/HApp.h | 5 ++--- src/simplex/HEkk.cpp | 20 +++++++++++--------- src/simplex/HEkk.h | 7 ++++--- 6 files changed, 56 insertions(+), 31 deletions(-) diff --git a/check/TestLpSolvers.cpp b/check/TestLpSolvers.cpp index c1470fbb58..49da8322b0 100644 --- a/check/TestLpSolvers.cpp +++ b/check/TestLpSolvers.cpp @@ -644,18 +644,38 @@ TEST_CASE("standard-form-lp", "[highs_lp_solver]") { } TEST_CASE("simplex-stats", "[highs_lp_solver]") { - HighsStatus return_status; + HighsStatus return_status; Highs h; - // h.setOptionValue("output_flag", dev_run); - std::string model_file = - std::string(HIGHS_DIR) + "/check/instances/adlittle.mps"; - REQUIRE(h.readModel(model_file) == HighsStatus::kOk); const HighsSimplexStats& simplex_stats = h.getSimplexStats(); - simplex_stats.report(stdout); - h.reportSimplexStats(stdout); - REQUIRE(h.run() == HighsStatus::kOk); - simplex_stats.report(stdout); - h.reportSimplexStats(stdout); - + h.setOptionValue("output_flag", dev_run); + std::string model_file = + std::string(HIGHS_DIR) + "/check/instances/adlittle.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.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 (dev_run) h.reportSimplexStats(stdout); + + h.clearSolver(); + h.setOptionValue("presolve", kHighsOffString); + REQUIRE(h.run() == HighsStatus::kOk); + REQUIRE(simplex_stats.valid); + 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 (dev_run) h.reportSimplexStats(stdout); } diff --git a/src/Highs.h b/src/Highs.h index e84558039d..70d800a5de 100644 --- a/src/Highs.h +++ b/src/Highs.h @@ -1216,8 +1216,12 @@ class Highs { // Start of advanced methods for HiGHS MIP solver - const HighsSimplexStats& getSimplexStats() const { return ekk_instance_.getSimplexStats(); } - void reportSimplexStats(FILE* file) const { ekk_instance_.reportSimplexStats(file); } + const HighsSimplexStats& getSimplexStats() const { + return ekk_instance_.getSimplexStats(); + } + void reportSimplexStats(FILE* file) const { + ekk_instance_.reportSimplexStats(file); + } /** * @brief Get the hot start basis data from the most recent simplex diff --git a/src/lp_data/HStruct.h b/src/lp_data/HStruct.h index 86a2bde39c..35a0b0ee42 100644 --- a/src/lp_data/HStruct.h +++ b/src/lp_data/HStruct.h @@ -164,9 +164,8 @@ struct HighsSimplexStats { double row_ep_density; double row_ap_density; double row_DSE_density; - void report(FILE* file) const; - void clear(); + void report(FILE* file, const std::string message = "") const; + void initialise(const HighsInt iteration_count_ = 0); }; - #endif /* LP_DATA_HSTRUCT_H_ */ diff --git a/src/simplex/HApp.h b/src/simplex/HApp.h index 905a290c3a..b8de2a3f59 100644 --- a/src/simplex/HApp.h +++ b/src/simplex/HApp.h @@ -112,9 +112,8 @@ inline HighsStatus solveLpSimplex(HighsLpSolverObject& solver_object) { // return resetModelStatusAndHighsInfo(solver_object); - // Clear the simplex stats - ekk_instance.clearSimplexStats(); - ekk_instance.simplex_stats_.iteration_count = -ekk_instance.iteration_count_; + // Initialise the simplex stats + ekk_instance.initialiseSimplexStats(); // Assumes that the LP has a positive number of rows, since // unconstrained LPs should be solved in solveLp diff --git a/src/simplex/HEkk.cpp b/src/simplex/HEkk.cpp index 126b56b364..caa4e641e0 100644 --- a/src/simplex/HEkk.cpp +++ b/src/simplex/HEkk.cpp @@ -296,7 +296,7 @@ void HEkk::invalidate() { assert(!this->status_.is_permuted); this->status_.initialised_for_solve = false; this->invalidateBasisMatrix(); - this->simplex_stats_.clear(); + this->simplex_stats_.initialise(); } void HEkk::invalidateBasisMatrix() { @@ -3509,7 +3509,8 @@ HighsStatus HEkk::returnFromEkkSolve(const HighsStatus return_status) { simplex_stats_.iteration_count += iteration_count_; // simplex_stats_.num_invert is incremented internally simplex_stats_.last_invert_num_el = simplex_nla_.factor_.invert_num_el; - simplex_stats_.last_factored_basis_num_el = simplex_nla_.factor_.basis_matrix_num_el; + simplex_stats_.last_factored_basis_num_el = + simplex_nla_.factor_.basis_matrix_num_el; simplex_stats_.col_aq_density = analysis_.col_aq_density; simplex_stats_.row_ep_density = analysis_.row_ep_density; simplex_stats_.row_ap_density = analysis_.row_ap_density; @@ -4420,23 +4421,24 @@ void HEkk::unitBtranResidual(const HighsInt row_out, const HVector& row_ep, } } -void HighsSimplexStats::report(FILE* file) const { - fprintf(file, "\nSimplex stats\n"); +void HighsSimplexStats::report(FILE* file, std::string message) const { + fprintf(file, "\nSimplex stats: %s\n", message.c_str()); fprintf(file, " valid = %d\n", this->valid); fprintf(file, " iteration_count = %d\n", this->iteration_count); fprintf(file, " num_invert = %d\n", this->num_invert); - fprintf(file, " last_invert_num_el = %d\n", this->last_invert_num_el); - fprintf(file, " last_factored_basis_num_el = %d\n", this->last_factored_basis_num_el); + fprintf(file, " last_invert_num_el = %d\n", + this->last_invert_num_el); + fprintf(file, " last_factored_basis_num_el = %d\n", + this->last_factored_basis_num_el); fprintf(file, " col_aq_density = %g\n", this->col_aq_density); fprintf(file, " row_ep_density = %g\n", this->row_ep_density); fprintf(file, " row_ap_density = %g\n", this->row_ap_density); fprintf(file, " row_DSE_density = %g\n", this->row_DSE_density); - } -void HighsSimplexStats::clear() { +void HighsSimplexStats::initialise(const HighsInt iteration_count_) { valid = false; - iteration_count = 0; + iteration_count = -iteration_count_; num_invert = 0; last_invert_num_el = 0; last_factored_basis_num_el = 0; diff --git a/src/simplex/HEkk.h b/src/simplex/HEkk.h index 9d54524fbc..0b253bebc0 100644 --- a/src/simplex/HEkk.h +++ b/src/simplex/HEkk.h @@ -157,8 +157,10 @@ class HEkk { const vector& rowUpper); const HighsSimplexStats& getSimplexStats() const { return simplex_stats_; } - void clearSimplexStats() { simplex_stats_.clear(); } - void reportSimplexStats(FILE* file) const { simplex_stats_.report(file); } + void initialiseSimplexStats() { simplex_stats_.initialise(iteration_count_); } + void reportSimplexStats(FILE* file, const std::string message = "") const { + simplex_stats_.report(file, message); + } // Make this private later void chooseSimplexStrategyThreads(const HighsOptions& options, @@ -175,7 +177,6 @@ class HEkk { const std::string message, const HighsInt alt_debug_level = -1) const; bool debugNlaScalingOk(const HighsLp& lp) const; - // Data members HighsCallback* callback_; HighsOptions* options_;