Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
lp_data_utils.h
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Utility helpers for manipulating LinearProgram and other types defined in
15// lp_data.
16
17#ifndef OR_TOOLS_LP_DATA_LP_DATA_UTILS_H_
18#define OR_TOOLS_LP_DATA_LP_DATA_UTILS_H_
19
20#include "ortools/glop/parameters.pb.h"
25
26namespace operations_research {
27namespace glop {
28
29// For all constraints in linear_program, if the constraint has a slack
30// variable, change its value in *values so that the constraints itself is
31// satisfied.
32// Note that this obviously won't always imply that the bounds of the slack
33// variable itself will be satisfied.
34// The code assumes (and DCHECKs) that all constraints with a slack variable
35// have their upper and lower bounds both set to 0. This is ensured by
36// LinearProgram::AddSlackVariablesWhereNecessary().
37void ComputeSlackVariablesValues(const LinearProgram& linear_program,
38 DenseRow* values);
39
40// This is separated from LinearProgram class because of a cyclic dependency
41// when scaling as an LP.
42void Scale(LinearProgram* lp, SparseMatrixScaler* scaler,
43 GlopParameters::ScalingAlgorithm scaling_method);
44
45// A convenience method for above providing a default algorithm for callers that
46// don't specify one.
47void Scale(LinearProgram* lp, SparseMatrixScaler* scaler);
48
49// Class to facilitate the conversion between an original "unscaled" LP problem
50// and its scaled version. It is easy to get the direction wrong, so it make
51// sense to have a single place where all the scaling formulas are kept.
53 public:
54 // Clear all scaling coefficients.
55 void Clear();
56
57 // Scale the given LP.
58 void Scale(LinearProgram* lp);
59 void Scale(const GlopParameters& params, LinearProgram* lp);
60 void ConfigureFromFactors(absl::Span<const double> row_factors,
61 absl::Span<const double> col_factors);
62
63 // Transforms value from unscaled domain to the scaled one.
64 Fractional ScaleVariableValue(ColIndex col, Fractional value) const;
65 Fractional ScaleReducedCost(ColIndex col, Fractional value) const;
66 Fractional ScaleDualValue(RowIndex row, Fractional value) const;
67 Fractional ScaleConstraintActivity(RowIndex row, Fractional value) const;
68
69 // Transforms corresponding value from the scaled domain to the original one.
70 Fractional UnscaleVariableValue(ColIndex col, Fractional value) const;
71 Fractional UnscaleReducedCost(ColIndex col, Fractional value) const;
72 Fractional UnscaleDualValue(RowIndex row, Fractional value) const;
73 Fractional UnscaleLeftSolveValue(RowIndex row, Fractional value) const;
74 Fractional UnscaleConstraintActivity(RowIndex row, Fractional value) const;
75
76 // Unscale a row vector v such that v.B = unit_row. When basis_col is the
77 // index of the Column that correspond to the unit position in matrix B.
78 void UnscaleUnitRowLeftSolve(ColIndex basis_col,
79 ScatteredRow* left_inverse) const;
80
81 // Unscale a col vector v such that B.c = matrix_column_col.
82 void UnscaleColumnRightSolve(const RowToColMapping& basis, ColIndex col,
83 ScatteredColumn* right_inverse) const;
84
85 // A variable value in the original domain must be multiplied by this factor
86 // to be in the scaled domain.
87 Fractional VariableScalingFactor(ColIndex col) const;
88
89 // Same as VariableScalingFactor() except that ColIndex greater than the
90 // number of columns will be interpreted as "slack" variable whose scaling
91 // factor depends on the row.
93
94 // Extra scaling function, to scale objective/bounds.
95 void AverageCostScaling(DenseRow* objective);
96 void ContainOneBoundScaling(DenseRow* upper_bounds, DenseRow* lower_bounds);
97
98 // Visible for testing. All variable/constraint bounds of the original LP
99 // where multiplied by this factor. Nothing else changed.
100 Fractional BoundsScalingFactor() const { return bound_scaling_factor_; }
101
102 // Visible for testing. All objective coefficients of the original LP where
103 // multiplied by this factor. Nothing else changed.
105 return objective_scaling_factor_;
106 }
107
108 private:
109 Fractional RowUnscalingFactor(RowIndex row) const {
110 return matrix_is_scaled_ ? row_unscaling_factors_[row] : 1.0;
111 }
112 Fractional ColUnscalingFactor(ColIndex col) const {
113 return matrix_is_scaled_ ? col_unscaling_factors_[col] : 1.0;
114 }
115
116 bool matrix_is_scaled_ = false;
117 DenseColumn row_unscaling_factors_;
118 DenseRow col_unscaling_factors_;
119
120 Fractional bound_scaling_factor_ = 1.0;
121 Fractional objective_scaling_factor_ = 1.0;
122};
123
124} // namespace glop
125} // namespace operations_research
126
127#endif // OR_TOOLS_LP_DATA_LP_DATA_UTILS_H_
void UnscaleUnitRowLeftSolve(ColIndex basis_col, ScatteredRow *left_inverse) const
void AverageCostScaling(DenseRow *objective)
Extra scaling function, to scale objective/bounds.
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
Transforms value from unscaled domain to the scaled one.
Fractional UnscaleDualValue(RowIndex row, Fractional value) const
void ContainOneBoundScaling(DenseRow *upper_bounds, DenseRow *lower_bounds)
Fractional UnscaleConstraintActivity(RowIndex row, Fractional value) const
void Clear()
Clear all scaling coefficients.
Fractional UnscaleLeftSolveValue(RowIndex row, Fractional value) const
Fractional ScaleDualValue(RowIndex row, Fractional value) const
void Scale(LinearProgram *lp)
Scale the given 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
Transforms corresponding value from the scaled domain to the original one.
Fractional ScaleReducedCost(ColIndex col, Fractional value) const
void UnscaleColumnRightSolve(const RowToColMapping &basis, ColIndex col, ScatteredColumn *right_inverse) const
Unscale a col vector v such that B.c = matrix_column_col.
StrictITIVector< RowIndex, ColIndex > RowToColMapping
Definition lp_types.h:394
void ComputeSlackVariablesValues(const LinearProgram &linear_program, DenseRow *values)
void Scale(LinearProgram *lp, SparseMatrixScaler *scaler)
StrictITIVector< RowIndex, Fractional > DenseColumn
Column-vector types. Column-vector types are indexed by a row index.
Definition lp_types.h:380
StrictITIVector< ColIndex, Fractional > DenseRow
Row-vector types. Row-vector types are indexed by a column index.
Definition lp_types.h:351
In SWIG mode, we don't want anything besides these top-level includes.