Skip to content

Commit

Permalink
Corrected IPX stats when kk1 has 0 iterations; formatted
Browse files Browse the repository at this point in the history
  • Loading branch information
jajhall committed Dec 2, 2024
1 parent 0861f04 commit 3c98069
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 105 deletions.
3 changes: 2 additions & 1 deletion check/TestLpSolvers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,8 @@ TEST_CASE("ipx-stats", "[highs_lp_solver]") {
REQUIRE(ipx_stats.num_row > 0);
REQUIRE(ipx_stats.num_nz > 0);
REQUIRE(ipx_stats.iteration_count > 0);
for (HighsInt iteration = 0; iteration < ipx_stats.iteration_count; iteration++) {
for (HighsInt iteration = 0; iteration < ipx_stats.iteration_count;
iteration++) {
REQUIRE(ipx_stats.cr_count[iteration] > 0);
if (ipx_stats.cr_type[iteration] == 2) {
REQUIRE(ipx_stats.factored_basis_num_el[iteration] > 0);
Expand Down
2 changes: 1 addition & 1 deletion src/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1527,7 +1527,7 @@ class Highs {
//
// Invalidates all solver data in Highs class members by calling
// invalidateModelStatus(), invalidateSolution(), invalidateBasis(),
// invalidateInfo(), invalidateEkk(), invalidateIis(),
// invalidateInfo(), invalidateEkk(), invalidateIis(),
// invalidateSimplexStats() and invalidateIpxStats();
void invalidateUserSolverData();
//
Expand Down
87 changes: 41 additions & 46 deletions src/ipm/IpxWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1089,90 +1089,85 @@ void reportSolveData(const HighsLogOptions& log_options,
ipx_info.volume_increase);
}

double HighsIpxStats::workEstimate() const {
return 0;
}
double HighsIpxStats::workEstimate() const { return 0; }

void HighsIpxStats::report(FILE* file, const std::string message, const HighsInt style) const {
void HighsIpxStats::report(FILE* file, const std::string message,
const HighsInt style) const {
if (style == HighsSolverStatsReportPretty) {
fprintf(file, "\nIpx stats: %s\n", message.c_str());
fprintf(file, " valid = %d\n", this->valid);
fprintf(file, " num_col = %d\n",
this->num_col);
fprintf(file, " num_row = %d\n",
this->num_row);
fprintf(file, " num_nz = %d\n",
this->num_nz);
fprintf(file, " num_col = %d\n", this->num_col);
fprintf(file, " num_row = %d\n", this->num_row);
fprintf(file, " num_nz = %d\n", this->num_nz);
fprintf(file, " iteration_count = %d\n",
this->iteration_count);
if (this->iteration_count != HighsInt(cr_type.size()))
printf("iteration_count = %d != %d = cr_type.size()\n",
int(this->iteration_count),
int(this->cr_type.size()));
int(this->iteration_count), int(this->cr_type.size()));
if (this->iteration_count != HighsInt(cr_count.size()))
printf("iteration_count = %d != %d = cr_count.size()\n",
int(this->iteration_count),
int(this->cr_count.size()));
int(this->iteration_count), int(this->cr_count.size()));
if (this->iteration_count != HighsInt(invert_num_el.size()))
printf("iteration_count = %d != %d = invert_num_el.size()\n",
int(this->iteration_count),
int(this->invert_num_el.size()));
int(this->iteration_count), int(this->invert_num_el.size()));
if (this->iteration_count != HighsInt(factored_basis_num_el.size()))
printf("iteration_count = %d != %d = factored_basis_num_el.size()\n",
int(this->iteration_count),
int(this->factored_basis_num_el.size()));
int(this->iteration_count),
int(this->factored_basis_num_el.size()));
assert(this->iteration_count == HighsInt(this->cr_type.size()));
assert(this->iteration_count == HighsInt(this->cr_count.size()));
assert(this->iteration_count == HighsInt(this->invert_num_el.size()));
assert(this->iteration_count == HighsInt(this->factored_basis_num_el.size()));
assert(this->iteration_count ==
HighsInt(this->factored_basis_num_el.size()));
fprintf(file, " Iter type cr_count basisNz invertNz\n");
//rintf(file, " dddd d ddddd ddddddd ddddddd\n");
// rintf(file, " dddd d ddddd ddddddd ddddddd\n");
for (HighsInt iteration = 0; iteration < iteration_count; iteration++) {
fprintf(file, " %4d %1d %5d %7d %7d\n",
int(iteration),
int(this->cr_type[iteration]),
int(this->cr_count[iteration]),
int(this->factored_basis_num_el[iteration]),
int(this->invert_num_el[iteration]));
fprintf(file, " %4d %1d %5d %7d %7d\n", int(iteration),
int(this->cr_type[iteration]), int(this->cr_count[iteration]),
int(this->factored_basis_num_el[iteration]),
int(this->invert_num_el[iteration]));
}
} else if (style == HighsSolverStatsReportCsvHeader) {
fprintf(file, "valid,col,row,nz,iteration_count,cr_count,iteration_count, cr_count,matrix_nz,invert_nz,");
fprintf(file,
"valid,col,row,nz,iteration_count,cr_count,iteration_count, "
"cr_count,matrix_nz,invert_nz,");
} else if (style == HighsSolverStatsReportCsvData) {
HighsInt num_type1_iteration = 0;
HighsInt num_type2_iteration = 0;
double average_type1_cr_count = 0;
double average_type2_cr_count = 0;
double average_type2_matrix_nz= 0;
double average_type2_matrix_nz = 0;
double average_type2_invert_nz = 0;
for (HighsInt iteration = 0; iteration < this->iteration_count; iteration++) {
for (HighsInt iteration = 0; iteration < this->iteration_count;
iteration++) {
if (this->cr_type[iteration] == 1) {
num_type1_iteration++;
average_type1_cr_count += this->cr_count[iteration];
num_type1_iteration++;
average_type1_cr_count += this->cr_count[iteration];
} else {
num_type2_iteration++;
average_type2_cr_count += this->cr_count[iteration];
average_type2_matrix_nz += this->factored_basis_num_el[iteration];
average_type2_invert_nz += this->invert_num_el[iteration];
}
num_type2_iteration++;
average_type2_cr_count += this->cr_count[iteration];
average_type2_matrix_nz += this->factored_basis_num_el[iteration];
average_type2_invert_nz += this->invert_num_el[iteration];
}
}
if (num_type1_iteration)
average_type1_cr_count /= (1.0 *num_type1_iteration);
if (num_type1_iteration)
average_type1_cr_count /= (1.0 * num_type1_iteration);
if (num_type2_iteration) {
average_type2_cr_count /= (1.0 *num_type2_iteration);
average_type2_matrix_nz /= (1.0 *num_type2_iteration);
average_type2_invert_nz /= (1.0 *num_type2_iteration);
}
average_type2_cr_count /= (1.0 * num_type2_iteration);
average_type2_matrix_nz /= (1.0 * num_type2_iteration);
average_type2_invert_nz /= (1.0 * num_type2_iteration);
}
fprintf(file, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,", int(this->valid),
int(this->num_col), int(this->num_row), int(this->num_nz),
int(this->num_col), int(this->num_row), int(this->num_nz),
int(num_type1_iteration), int(average_type1_cr_count),
int(num_type2_iteration), int(average_type2_cr_count),
int(average_type2_matrix_nz), int(average_type2_invert_nz));
int(num_type2_iteration), int(average_type2_cr_count),
int(average_type2_matrix_nz), int(average_type2_invert_nz));
} else {
fprintf(file, "Unknown IPX stats report style of %d\n", int(style));
assert(123 == 456);
}
}

void HighsIpxStats::initialise() {
valid = false;
iteration_count = 0;
Expand Down
16 changes: 7 additions & 9 deletions src/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1320,7 +1320,7 @@ HighsStatus Highs::solve() {
solveLp(incumbent_lp, "Not presolved: solving the LP",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
presolved_lp_simplex_stats_ = simplex_stats_;
presolved_lp_simplex_stats_ = simplex_stats_;
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
if (return_status == HighsStatus::kError)
Expand All @@ -1334,7 +1334,7 @@ HighsStatus Highs::solve() {
solveLp(incumbent_lp, "Problem not reduced by presolve: solving the LP",
this_solve_original_lp_time);
simplex_stats_ = this->ekk_instance_.getSimplexStats();
presolved_lp_simplex_stats_ = simplex_stats_;
presolved_lp_simplex_stats_ = simplex_stats_;
return_status = interpretCallStatus(options_.log_options, call_status,
return_status, "callSolveLp");
if (return_status == HighsStatus::kError)
Expand Down Expand Up @@ -2334,8 +2334,8 @@ HighsStatus Highs::setBasis(const HighsBasis& basis,
HighsBasis modifiable_basis = basis;
modifiable_basis.was_alien = true;
HighsLpSolverObject solver_object(model_.lp_, modifiable_basis, solution_,
info_, ekk_instance_, ipx_stats_, callback_,
options_, timer_);
info_, ekk_instance_, ipx_stats_,
callback_, options_, timer_);
HighsStatus return_status = formSimplexLpBasisAndFactor(solver_object);
if (return_status != HighsStatus::kOk) return HighsStatus::kError;
// Update the HiGHS basis
Expand Down Expand Up @@ -3637,9 +3637,7 @@ void Highs::invalidateSimplexStats() {
presolved_lp_simplex_stats_.initialise();
}

void Highs::invalidateIpxStats() {
ipx_stats_.initialise();
}
void Highs::invalidateIpxStats() { ipx_stats_.initialise(); }

HighsStatus Highs::completeSolutionFromDiscreteAssignment() {
// Determine whether the current solution of a MIP is feasible and,
Expand Down Expand Up @@ -3782,8 +3780,8 @@ HighsStatus Highs::completeSolutionFromDiscreteAssignment() {
HighsStatus Highs::callSolveLp(HighsLp& lp, const string message) {
HighsStatus return_status = HighsStatus::kOk;

HighsLpSolverObject solver_object(lp, basis_, solution_, info_, ekk_instance_, ipx_stats_,
callback_, options_, timer_);
HighsLpSolverObject solver_object(lp, basis_, solution_, info_, ekk_instance_,
ipx_stats_, callback_, options_, timer_);

// Check that the model is column-wise
assert(model_.lp_.a_matrix_.isColwise());
Expand Down
7 changes: 4 additions & 3 deletions src/lp_data/HighsInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,8 +1435,8 @@ HighsStatus Highs::getBasicVariablesInterface(HighsInt* basic_variables) {
// The LP has no invert to use, so have to set one up, but only
// for the current basis, so return_value is the rank deficiency.
HighsLpSolverObject solver_object(lp, basis_, solution_, info_,
ekk_instance_, ipx_stats_,
callback_, options_, timer_);
ekk_instance_, ipx_stats_, callback_,
options_, timer_);
const bool only_from_known_basis = true;
return_status = interpretCallStatus(
options_.log_options,
Expand Down Expand Up @@ -1945,7 +1945,8 @@ HighsStatus Highs::getPrimalRayInterface(bool& has_primal_ray,

HighsStatus Highs::getRangingInterface() {
HighsLpSolverObject solver_object(model_.lp_, basis_, solution_, info_,
ekk_instance_, ipx_stats_, callback_, options_, timer_);
ekk_instance_, ipx_stats_, callback_,
options_, timer_);
solver_object.model_status_ = model_status_;
return getRangingData(this->ranging_, solver_object);
}
Expand Down
8 changes: 4 additions & 4 deletions src/lp_data/HighsLpSolverObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@
class HighsLpSolverObject {
public:
HighsLpSolverObject(HighsLp& lp, HighsBasis& basis, HighsSolution& solution,
HighsInfo& highs_info, HEkk& ekk_instance, HighsIpxStats& ipx_stats,
HighsCallback& callback, HighsOptions& options,
HighsTimer& timer)
HighsInfo& highs_info, HEkk& ekk_instance,
HighsIpxStats& ipx_stats, HighsCallback& callback,
HighsOptions& options, HighsTimer& timer)
: lp_(lp),
basis_(basis),
solution_(solution),
highs_info_(highs_info),
ekk_instance_(ekk_instance),
ipx_stats_(ipx_stats),
ipx_stats_(ipx_stats),
callback_(callback),
options_(options),
timer_(timer) {}
Expand Down
12 changes: 7 additions & 5 deletions src/lp_data/HighsOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ struct HighsOptionsStruct {
icrash_breakpoints(false),
mip_detect_symmetry(false),
mip_allow_restart(false),
mip_old_analytic_centre_method(false),
mip_old_analytic_centre_method(false),
mip_max_nodes(0),
mip_max_stall_nodes(0),
mip_max_start_nodes(0),
Expand Down Expand Up @@ -949,9 +949,10 @@ class HighsOptions : public HighsOptionsStruct {
advanced, &mip_allow_restart, true);
records.push_back(record_bool);

record_bool = new OptionRecordBool("mip_old_analytic_centre_method",
"Use origial or new analytic centre method in MIP",
advanced, &mip_old_analytic_centre_method, true);
record_bool =
new OptionRecordBool("mip_old_analytic_centre_method",
"Use origial or new analytic centre method in MIP",
advanced, &mip_old_analytic_centre_method, true);
records.push_back(record_bool);

record_int = new OptionRecordInt("mip_max_nodes",
Expand Down Expand Up @@ -1049,7 +1050,8 @@ class HighsOptions : public HighsOptionsStruct {

record_int = new OptionRecordInt(
"mip_compute_analytic_centre",
"Compute analytic centre for MIP: -1 => choose; 0 => off; 1 => on (default)",
"Compute analytic centre for MIP: -1 => choose; 0 => off; 1 => on "
"(default)",
advanced, &mip_compute_analytic_centre, kMipAnalyticCentreCalulationMin,
kMipAnalyticCentreCalulationOn, kMipAnalyticCentreCalulationMax);
records.push_back(record_int);
Expand Down
7 changes: 3 additions & 4 deletions src/lp_data/HighsSolverStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ struct HighsSimplexStats {
double row_ap_density;
double row_DSE_density;
double workEstimate() const;
void report(FILE* file,
const std::string message = "",
const HighsInt style = HighsSolverStatsReportPretty) const;
void report(FILE* file, const std::string message = "",
const HighsInt style = HighsSolverStatsReportPretty) const;
void initialise(const HighsInt iteration_count_ = 0);
};

Expand All @@ -56,7 +55,7 @@ struct HighsIpxStats {
std::vector<HighsInt> invert_num_el;
double workEstimate() const;
void report(FILE* file, const std::string message = "",
const HighsInt style = HighsSolverStatsReportPretty) const;
const HighsInt style = HighsSolverStatsReportPretty) const;
void initialise();
};

Expand Down
10 changes: 6 additions & 4 deletions src/mip/HighsMipSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,13 @@ void HighsMipSolver::run() {
analysis_.mipTimerStop(kMipClockRunSetup);
if (analysis_.analyse_mip_time && !submip)
highsLogUser(options_mip_->log_options, HighsLogType::kInfo,
"MIP-Timing: %11.2g - completed setup\n",
timer_.read(timer_.total_clock));
"MIP-Timing: %11.2g - completed setup\n",
timer_.read(timer_.total_clock));
if (!submip) {
if (analysis_.analyse_mip_time) {
highsLogUser(options_mip_->log_options, HighsLogType::kInfo,
"MIP-Timing: %11.2g - starting relaxation simplex solve\n", timer_.read());
"MIP-Timing: %11.2g - starting relaxation simplex solve\n",
timer_.read());
analysis_.mipTimerStart(kMipClockRelaxationSimplexSolve);
analysis_.mipTimerStart(kMipClockSimplexNoBasisSolveLp);
}
Expand Down Expand Up @@ -199,7 +200,8 @@ void HighsMipSolver::run() {
analysis_.mipTimerStop(kMipClockSimplexNoBasisSolveLp);
analysis_.mipTimerStop(kMipClockRelaxationSimplexSolve);
highsLogUser(options_mip_->log_options, HighsLogType::kInfo,
"MIP-Timing: %11.2g - completed relaxation simplex solve\n", timer_.read());
"MIP-Timing: %11.2g - completed relaxation simplex solve\n",
timer_.read());
}
}
restart:
Expand Down
10 changes: 6 additions & 4 deletions src/mip/HighsMipSolverData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void HighsMipSolverData::startAnalyticCenterComputation(
taskGroup.spawn([&]() {
// first check if the analytic centre computation should be cancelled, e.g.
// due to early return in the root node evaluation
const bool ac_logging = !mipsolver.submip; // 2049 unset this
const bool ac_logging = !mipsolver.submip; // 2049 unset this
Highs ipm;
if (mipsolver.options_mip_->mip_old_analytic_centre_method) {
// Original calculation is just IPM with crossover off
Expand All @@ -315,14 +315,15 @@ void HighsMipSolverData::startAnalyticCenterComputation(
}
ipm.setOptionValue("presolve", "off");
ipm.setOptionValue("output_flag", false);
ipm.setOptionValue("output_flag", !mipsolver.submip); // 2049 unset this ultimately
ipm.setOptionValue("output_flag",
!mipsolver.submip); // 2049 unset this ultimately
ipm.setOptionValue("ipm_iteration_limit", 200);
double time_available =
std::max(mipsolver.options_mip_->time_limit -
mipsolver.timer_.read(mipsolver.timer_.total_clock),
0.1);
ipm.setOptionValue("time_limit", time_available);
ipm.setOptionValue("kkt_logging", !mipsolver.submip); // 2049 unset this
ipm.setOptionValue("kkt_logging", !mipsolver.submip); // 2049 unset this
// ultimately
//
// cr1_iteration_limit is what's set internal to IPX to limit the
Expand All @@ -349,7 +350,8 @@ void HighsMipSolverData::startAnalyticCenterComputation(
lpmodel.col_cost_.assign(lpmodel.num_col_, 0.0);
ipm.passModel(std::move(lpmodel));

// if (!mipsolver.submip)ipm.writeModel(mipsolver.model_->model_name_ + "_ipm.mps");
// if (!mipsolver.submip)ipm.writeModel(mipsolver.model_->model_name_ +
// "_ipm.mps");

if (ac_logging) num_analytic_centre_start++;
double tt0 = mipsolver.timer_.read(mipsolver.timer_.total_clock);
Expand Down
2 changes: 1 addition & 1 deletion src/mip/HighsMipSolverData.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct HighsMipSolverData {
HighsInt numRestartsRoot;
HighsInt numCliqueEntriesAfterPresolve;
HighsInt numCliqueEntriesAfterFirstPresolve;
HighsSimplexStats simplex_stats;
HighsSimplexStats simplex_stats;

std::vector<HighsInt> ARstart_;
std::vector<HighsInt> ARindex_;
Expand Down
5 changes: 3 additions & 2 deletions src/mip/MipTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ class MipTimer {
clock[kMipClockInit] = timer_pointer->clock_def("Initialise");
clock[kMipClockRunPresolve] = timer_pointer->clock_def("Run presolve");
clock[kMipClockRunSetup] = timer_pointer->clock_def("Run setup");
clock[kMipClockRelaxationSimplexSolve] = timer_pointer->clock_def("Relaxation simplex solve");
clock[kMipClockRelaxationSimplexSolve] =
timer_pointer->clock_def("Relaxation simplex solve");
clock[kMipClockTrivialHeuristics] =
timer_pointer->clock_def("Trivial heuristics");
clock[kMipClockEvaluateRootNode] =
Expand Down Expand Up @@ -257,7 +258,7 @@ class MipTimer {
const std::vector<HighsInt> mip_clock_list{kMipClockInit,
kMipClockRunPresolve,
kMipClockRunSetup,
kMipClockRelaxationSimplexSolve,
kMipClockRelaxationSimplexSolve,
kMipClockTrivialHeuristics,
kMipClockEvaluateRootNode,
kMipClockPerformAging0,
Expand Down
Loading

0 comments on commit 3c98069

Please sign in to comment.