OR-Tools  9.3
dual_edge_norms.h
Go to the documentation of this file.
1// Copyright 2010-2021 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#ifndef OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_
15#define OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_
16
18#include "ortools/glop/parameters.pb.h"
23#include "ortools/util/stats.h"
24
25namespace operations_research {
26namespace glop {
27
28// This class maintains the dual edge squared norms to be used in the
29// dual steepest edge pricing. The dual edge u_i associated with a basic
30// variable of row index i is such that u_i.B = e_i where e_i is the unit row
31// vector with a 1.0 at position i and B the current basis. We call such vector
32// u_i an unit row left inverse, and it can be computed by
33//
34// basis_factorization.LeftSolveForUnitRow(i, &u_i);
35//
36// Instead of computing each ||u_i|| at every iteration, it is more efficient to
37// update them incrementally for each basis pivot applied to B. See the code or
38// the papers below for details:
39//
40// J.J. Forrest, D. Goldfarb, "Steepest-edge simplex algorithms for linear
41// programming", Mathematical Programming 57 (1992) 341-374, North-Holland.
42// http://www.springerlink.com/content/q645w3t2q229m248/
43//
44// Achim Koberstein, "The dual simplex method, techniques for a fast and stable
45// implementation", PhD, Paderborn, Univ., 2005.
46// http://digital.ub.uni-paderborn.de/hs/download/pdf/3885?originalFilename=true
48 public:
49 // Takes references to the linear program data we need.
50 explicit DualEdgeNorms(const BasisFactorization& basis_factorization);
51
52 // Clears, i.e. reset the object to its initial value. This will trigger a
53 // full norm recomputation on the next GetEdgeSquaredNorms().
54 void Clear();
55
56 // When we just add new constraints to the matrix and use an incremental
57 // solve, we do not need to recompute the norm of the old rows, and the norm
58 // of the new ones can be just set to 1 as long as we use identity columns for
59 // these.
60 void ResizeOnNewRows(RowIndex new_size);
61
62 // If this is true, then the caller must re-factorize the basis before the
63 // next call to GetEdgeSquaredNorms(). This is because the latter will
64 // recompute the norms from scratch and therefore needs a hightened precision
65 // and speed. This also indicates if GetEdgeSquaredNorms() will trigger a
66 // recomputation.
67 bool NeedsBasisRefactorization() const;
68
69 // Returns the dual edge squared norms. This is only valid if the caller
70 // properly called UpdateBeforeBasisPivot() before each basis pivot, or just
71 // called Clear().
73
74 // Updates the norms if the columns of the basis where permuted.
76
77 // Updates the norms just before a basis pivot is applied:
78 // - The column at leaving_row will leave the basis and the column at
79 // entering_col will enter it.
80 // - direction is the right inverse of the entering column.
81 // - unit_row_left_inverse is the left inverse of the unit row with index
82 // given by the leaving_row. This is also the leaving dual edge.
83 void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row,
84 const ScatteredColumn& direction,
85 const ScatteredRow& unit_row_left_inverse);
86
87 // Sets the algorithm parameters.
88 void SetParameters(const GlopParameters& parameters) {
89 parameters_ = parameters;
90 }
91
92 // Stats related functions.
93 std::string StatString() const { return stats_.StatString(); }
94
95 private:
96 // Recomputes the dual edge squared norms from scratch with maximum precision.
97 // The matrix must have been refactorized before because we will do a lot of
98 // inversions. See NeedsBasisRefactorization(). This is checked in debug mode.
99 void ComputeEdgeSquaredNorms();
100
101 // Computes the vector tau needed to update the norms using a right solve:
102 // B.tau = (u_i)^T, u_i.B = e_i for i = leaving_row.
103 const DenseColumn& ComputeTau(const ScatteredColumn& unit_row_left_inverse);
104
105 // Statistics.
106 struct Stats : public StatsGroup {
107 Stats()
108 : StatsGroup("DualEdgeNorms"),
109 tau_density("tau_density", this),
110 edge_norms_accuracy("edge_norms_accuracy", this),
111 lower_bounded_norms("lower_bounded_norms", this) {}
112 RatioDistribution tau_density;
113 DoubleDistribution edge_norms_accuracy;
114 IntegerDistribution lower_bounded_norms;
115 };
116 Stats stats_;
117
118 // Parameters.
119 GlopParameters parameters_;
120
121 // Problem data that should be updated from outside.
122 const BasisFactorization& basis_factorization_;
123
124 // The dual edge norms.
125 DenseColumn edge_squared_norms_;
126
127 // Whether we should recompute the norm from scratch.
128 bool recompute_edge_squared_norms_;
129
130 DISALLOW_COPY_AND_ASSIGN(DualEdgeNorms);
131};
132
133} // namespace glop
134} // namespace operations_research
135
136#endif // OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_
void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row, const ScatteredColumn &direction, const ScatteredRow &unit_row_left_inverse)
void UpdateDataOnBasisPermutation(const ColumnPermutation &col_perm)
DualEdgeNorms(const BasisFactorization &basis_factorization)
void SetParameters(const GlopParameters &parameters)
SatParameters parameters
StrictITIVector< RowIndex, Fractional > DenseColumn
Definition: lp_types.h:332
Collection of objects used to extend the Constraint Solver library.