MCPcopy Create free account
hub / github.com/ERGO-Code/HiGHS / computeExactDualObjectiveValue

Method computeExactDualObjectiveValue

highs/simplex/HEkkDual.cpp:2851–2961  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2849}
2850
2851double HEkkDual::computeExactDualObjectiveValue(HVector& dual_col,
2852 HVector& dual_row) {
2853 const HighsLp& lp = ekk_instance_.lp_;
2854 const SimplexBasis& basis = ekk_instance_.basis_;
2855 const HighsSimplexInfo& info = ekk_instance_.info_;
2856 // Create a local buffer for the pi vector
2857 dual_col.setup(lp.num_row_);
2858 dual_col.clear();
2859 for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
2860 HighsInt iVar = basis.basicIndex_[iRow];
2861 if (iVar < lp.num_col_) {
2862 const double value = lp.col_cost_[iVar];
2863 if (value) {
2864 dual_col.array[iRow] = value;
2865 dual_col.index[dual_col.count++] = iRow;
2866 }
2867 }
2868 }
2869 // Create a local buffer for the dual vector
2870 const HighsInt numTot = lp.num_col_ + lp.num_row_;
2871 dual_row.setup(lp.num_col_);
2872 dual_row.clear();
2873 if (dual_col.count) {
2874 const bool quad_precision = false;
2875 const double expected_density = 1;
2876 simplex_nla->btran(dual_col, expected_density);
2877 lp.a_matrix_.priceByColumn(quad_precision, dual_row, dual_col);
2878 }
2879 // Compute dual infeasibilities
2880 ekk_instance_.computeSimplexDualInfeasible();
2881 if (info.num_dual_infeasibilities > 0)
2882 highsLogDev(ekk_instance_.options_->log_options, HighsLogType::kInfo,
2883 "When computing exact dual objective, the unperturbed costs "
2884 "yield num / max / sum dual "
2885 "infeasibilities = %d / %g / %g\n",
2886 (int)info.num_dual_infeasibilities, info.max_dual_infeasibility,
2887 info.sum_dual_infeasibilities);
2888 HighsCDouble dual_objective = lp.offset_;
2889 double norm_dual = 0;
2890 double norm_delta_dual = 0;
2891 for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
2892 if (!basis.nonbasicFlag_[iCol]) continue;
2893 double exact_dual = lp.col_cost_[iCol] - dual_row.array[iCol];
2894 // The active value must be decided based on the exact dual. For a nonbasic
2895 // column the bound that must be used may flip due to cost perturbation
2896 // flipping the sign of its dual and for a basic variable we may need to add
2897 // to the dual objective using one of the bounds when its dual is not zero.
2898 double active_value;
2899 if (exact_dual > ekk_instance_.options_->small_matrix_value)
2900 active_value = lp.col_lower_[iCol];
2901 else if (exact_dual < -ekk_instance_.options_->small_matrix_value)
2902 active_value = lp.col_upper_[iCol];
2903 else
2904 active_value = info.workValue_[iCol];
2905
2906 // when the active value is infinite the dual objective lower bound is
2907 // -infinity
2908 if (highs_isInfinity(fabs(active_value))) return -kHighsInf;

Callers

nothing calls this directly

Calls 7

highsLogDevFunction · 0.85
highs_isInfinityFunction · 0.85
priceByColumnMethod · 0.80
setupMethod · 0.45
clearMethod · 0.45
btranMethod · 0.45

Tested by

no test coverage detected