Skip to content

Commit

Permalink
HighsSimplexStats struct gives data about last simplex solve
Browse files Browse the repository at this point in the history
  • Loading branch information
jajhall committed Nov 28, 2024
1 parent 9fdc611 commit 258e8c0
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 31 deletions.
42 changes: 31 additions & 11 deletions check/TestLpSolvers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
8 changes: 6 additions & 2 deletions src/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 2 additions & 3 deletions src/lp_data/HStruct.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
5 changes: 2 additions & 3 deletions src/simplex/HApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 11 additions & 9 deletions src/simplex/HEkk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions src/simplex/HEkk.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,10 @@ class HEkk {
const vector<double>& 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,
Expand All @@ -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_;
Expand Down

0 comments on commit 258e8c0

Please sign in to comment.