#include "simplex/HEkk.h"
void HEkk::initialiseControl() {
info_.allow_dual_steepest_edge_to_devex_switch =
options_->simplex_dual_edge_weight_strategy ==
kSimplexEdgeWeightStrategyChoose;
info_.dual_steepest_edge_weight_log_error_threshold =
options_->dual_steepest_edge_weight_log_error_threshold;
info_.control_iteration_count0 = iteration_count_;
info_.col_aq_density = 0;
info_.row_ep_density = 0;
info_.row_ap_density = 0;
info_.row_DSE_density = 0;
info_.col_steepest_edge_density = 0;
info_.col_basic_feasibility_change_density = 0;
info_.row_basic_feasibility_change_density = 0;
info_.col_BFRT_density = 0;
info_.primal_col_density = 0;
info_.dual_col_density = 1;
info_.costly_DSE_frequency = 0;
info_.num_costly_DSE_iteration = 0;
info_.costly_DSE_measure = 0;
info_.average_log_low_DSE_weight_error = 0;
info_.average_log_high_DSE_weight_error = 0;
}
void HEkk::updateOperationResultDensity(const double local_density,
double& density) const {
density = (1 - kRunningAverageMultiplier) * density +
kRunningAverageMultiplier * local_density;
}
void HEkk::assessDSEWeightError(const double computed_edge_weight,
const double updated_edge_weight) {
edge_weight_error_ = std::fabs(updated_edge_weight - computed_edge_weight) /
std::max(1.0, computed_edge_weight);
if (edge_weight_error_ > options_->dual_steepest_edge_weight_error_tolerance)
highsLogDev(options_->log_options, HighsLogType::kInfo,
"Dual steepest edge weight error is %g\n", edge_weight_error_);
double weight_relative_deviation;
if (updated_edge_weight < computed_edge_weight) {
weight_relative_deviation = computed_edge_weight / updated_edge_weight;
info_.average_log_low_DSE_weight_error =
0.99 * info_.average_log_low_DSE_weight_error +
0.01 * log(weight_relative_deviation);
} else {
weight_relative_deviation = updated_edge_weight / computed_edge_weight;
info_.average_log_high_DSE_weight_error =
0.99 * info_.average_log_high_DSE_weight_error +
0.01 * log(weight_relative_deviation);
}
}
bool HEkk::switchToDevex() {
const double kCostlyDseMeasureLimit = 1000.0;
const double kCostlyDseMinimumDensity = 0.01;
const double kCostlyDseFractionNumTotalIterationBeforeSwitch = 0.1;
const double kCostlyDseFractionNumCostlyDseIterationBeforeSwitch = 0.05;
bool switch_to_devex = false;
double costly_DSE_measure_denominator;
costly_DSE_measure_denominator = max(
max(info_.row_ep_density, info_.col_aq_density), info_.row_ap_density);
if (costly_DSE_measure_denominator > 0) {
info_.costly_DSE_measure =
info_.row_DSE_density / costly_DSE_measure_denominator;
info_.costly_DSE_measure =
info_.costly_DSE_measure * info_.costly_DSE_measure;
} else {
info_.costly_DSE_measure = 0;
}
bool costly_DSE_iteration =
info_.costly_DSE_measure > kCostlyDseMeasureLimit &&
info_.row_DSE_density > kCostlyDseMinimumDensity;
info_.costly_DSE_frequency =
(1 - kRunningAverageMultiplier) * info_.costly_DSE_frequency;
if (costly_DSE_iteration) {
info_.num_costly_DSE_iteration++;
info_.costly_DSE_frequency += kRunningAverageMultiplier * 1.0;
HighsInt local_iteration_count =
iteration_count_ - info_.control_iteration_count0;
HighsInt local_num_tot = lp_.num_col_ + lp_.num_row_;
switch_to_devex =
info_.allow_dual_steepest_edge_to_devex_switch &&
(info_.num_costly_DSE_iteration >
local_iteration_count *
kCostlyDseFractionNumCostlyDseIterationBeforeSwitch) &&
(local_iteration_count >
kCostlyDseFractionNumTotalIterationBeforeSwitch * local_num_tot);
if (switch_to_devex) {
highsLogDev(options_->log_options, HighsLogType::kInfo,
"Switch from DSE to Devex after %" HIGHSINT_FORMAT
" costly DSE iterations of %" HIGHSINT_FORMAT
" with "
"densities C_Aq = %11.4g; R_Ep = %11.4g; R_Ap = "
"%11.4g; DSE = %11.4g\n",
info_.num_costly_DSE_iteration, local_iteration_count,
info_.col_aq_density, info_.row_ep_density,
info_.row_ap_density, info_.row_DSE_density);
}
}
if (!switch_to_devex) {
double local_measure = info_.average_log_low_DSE_weight_error +
info_.average_log_high_DSE_weight_error;
double local_threshold =
info_.dual_steepest_edge_weight_log_error_threshold;
switch_to_devex = info_.allow_dual_steepest_edge_to_devex_switch &&
local_measure > local_threshold;
if (switch_to_devex) {
highsLogDev(options_->log_options, HighsLogType::kInfo,
"Switch from DSE to Devex with log error measure of %g > "
"%g = threshold\n",
local_measure, local_threshold);
}
}
return switch_to_devex;
}