20#include "absl/log/check.h"
21#include "absl/types/span.h"
44 scaler->
Init(&lp->matrix_);
48 &lp->objective_coefficients_);
50 &lp->variable_upper_bounds_);
52 &lp->variable_lower_bounds_);
55 lp->transpose_matrix_is_consistent_ =
false;
66 matrix_is_scaled_ =
true;
77 absl::Span<const double> row_factors,
78 absl::Span<const double> col_factors) {
79 matrix_is_scaled_ =
true;
80 const RowIndex num_rows(row_factors.size());
81 row_unscaling_factors_.resize(num_rows, 1.0);
82 for (RowIndex row(0); row < num_rows; ++row) {
83 row_unscaling_factors_[row] = 1.0 / row_factors[row.value()];
86 const ColIndex num_cols(col_factors.size());
87 col_unscaling_factors_.resize(num_cols, 1.0);
88 for (ColIndex col(0); col < num_cols; ++col) {
89 col_unscaling_factors_[col] = 1.0 / col_factors[col.value()];
94 matrix_is_scaled_ =
false;
95 bound_scaling_factor_ = 1.0;
96 objective_scaling_factor_ = 1.0;
102 return ColUnscalingFactor(col) * bound_scaling_factor_;
106 if (!matrix_is_scaled_)
return bound_scaling_factor_;
107 const ColIndex num_cols = col_unscaling_factors_.size();
108 if (col < num_cols) {
109 return col_unscaling_factors_[col] * bound_scaling_factor_;
111 return row_unscaling_factors_[
ColToRowIndex(col - num_cols)] *
112 bound_scaling_factor_;
117 return value * ColUnscalingFactor(col) * bound_scaling_factor_;
123 return value / ColUnscalingFactor(col) * objective_scaling_factor_;
129 return value * (RowUnscalingFactor(row) * objective_scaling_factor_);
135 return value / RowUnscalingFactor(row) * bound_scaling_factor_;
141 return value / (ColUnscalingFactor(col) * bound_scaling_factor_);
147 return value * ColUnscalingFactor(col) / objective_scaling_factor_;
153 return value / (RowUnscalingFactor(row) * objective_scaling_factor_);
161 return value / RowUnscalingFactor(row);
167 return value * RowUnscalingFactor(row) / bound_scaling_factor_;
172 const Fractional global_factor = ColUnscalingFactor(basis_col);
176 const ColIndex num_rows = left_inverse->
values.
size();
177 for (ColIndex col(0); col < num_rows; ++col) {
178 left_inverse->
values[col] /=
182 for (
const ColIndex col : left_inverse->
non_zeros) {
183 left_inverse->
values[col] /=
192 const Fractional global_factor = 1.0 / ColUnscalingFactor(col);
197 const RowIndex num_rows = right_inverse->
values.
size();
198 for (RowIndex row(0); row < num_rows; ++row) {
199 right_inverse->
values[row] /=
200 ColUnscalingFactor(basis[row]) * global_factor;
203 for (
const RowIndex row : right_inverse->
non_zeros) {
204 right_inverse->
values[row] /=
205 ColUnscalingFactor(basis[row]) * global_factor;
214 if (f == 0)
continue;
218 if (num_terms == 0) {
219 objective_scaling_factor_ = 1.0;
223 const Fractional average = sum /
static_cast<double>(num_terms);
224 objective_scaling_factor_ = 1.0 / average;
226 f *= objective_scaling_factor_;
232 const double infinity = std::numeric_limits<double>::infinity();
237 if (m == 0 || m == infinity)
continue;
238 min_magnitude = std::min(min_magnitude, m);
239 max_magnitude = std::max(max_magnitude, m);
243 if (m == 0 || m == infinity)
continue;
244 min_magnitude = std::min(min_magnitude, m);
245 max_magnitude = std::max(max_magnitude, m);
248 bound_scaling_factor_ = 1.0;
249 if (min_magnitude != infinity) {
250 CHECK_LE(min_magnitude, max_magnitude);
251 if (min_magnitude > 1.0) {
252 bound_scaling_factor_ = 1.0 / min_magnitude;
253 }
else if (max_magnitude < 1.0) {
254 bound_scaling_factor_ = 1.0 / max_magnitude;
258 if (bound_scaling_factor_ == 1.0)
return;
260 f *= bound_scaling_factor_;
263 f *= bound_scaling_factor_;
GlopParameters_ScalingAlgorithm ScalingAlgorithm
::operations_research::glop::GlopParameters_CostScalingAlgorithm cost_scaling() const
::operations_research::glop::GlopParameters_ScalingAlgorithm scaling_method() const
Fractional ScaleObjective(GlopParameters::CostScalingAlgorithm method)
ColIndex num_variables() const
RowIndex num_constraints() const
void UnscaleUnitRowLeftSolve(ColIndex basis_col, ScatteredRow *left_inverse) const
void AverageCostScaling(DenseRow *objective)
void ConfigureFromFactors(absl::Span< const double > row_factors, absl::Span< const double > col_factors)
Fractional VariableScalingFactorWithSlack(ColIndex col) const
Fractional ScaleVariableValue(ColIndex col, Fractional value) const
Fractional UnscaleDualValue(RowIndex row, Fractional value) const
void ContainOneBoundScaling(DenseRow *upper_bounds, DenseRow *lower_bounds)
Fractional UnscaleConstraintActivity(RowIndex row, Fractional value) const
Fractional UnscaleLeftSolveValue(RowIndex row, Fractional value) const
Fractional ScaleDualValue(RowIndex row, Fractional value) const
void Scale(LinearProgram *lp)
Fractional ScaleConstraintActivity(RowIndex row, Fractional value) const
Fractional UnscaleReducedCost(ColIndex col, Fractional value) const
Fractional VariableScalingFactor(ColIndex col) const
Fractional UnscaleVariableValue(ColIndex col, Fractional value) const
Fractional ScaleReducedCost(ColIndex col, Fractional value) const
void UnscaleColumnRightSolve(const RowToColMapping &basis, ColIndex col, ScatteredColumn *right_inverse) const
const DenseRow & col_scales() const
void ScaleColumnVector(bool up, DenseColumn *column_vector) const
const DenseColumn & row_scales() const
void Init(SparseMatrix *matrix)
void ScaleRowVector(bool up, DenseRow *row_vector) const
void Scale(GlopParameters::ScalingAlgorithm method)
void resize(IntType size)
StrictITIVector< RowIndex, ColIndex > RowToColMapping
RowIndex ColToRowIndex(ColIndex col)
void Scale(LinearProgram *lp, SparseMatrixScaler *scaler)
StrictITIVector< ColIndex, Fractional > DenseRow
StrictITIVector< Index, Fractional > values
std::vector< Index > non_zeros