Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
dual_edge_norms.h
Go to the documentation of this file.
1// Copyright 2010-2024 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
17#include <string>
18
20#include "ortools/glop/parameters.pb.h"
25#include "ortools/util/stats.h"
26
27namespace operations_research {
28namespace glop {
29
30// This class maintains the dual edge squared norms to be used in the
31// dual steepest edge pricing. The dual edge u_i associated with a basic
32// variable of row index i is such that u_i.B = e_i where e_i is the unit row
33// vector with a 1.0 at position i and B the current basis. We call such vector
34// u_i an unit row left inverse, and it can be computed by
35//
36// basis_factorization.LeftSolveForUnitRow(i, &u_i);
37//
38// Instead of computing each ||u_i|| at every iteration, it is more efficient to
39// update them incrementally for each basis pivot applied to B. See the code or
40// the papers below for details:
41//
42// J.J. Forrest, D. Goldfarb, "Steepest-edge simplex algorithms for linear
43// programming", Mathematical Programming 57 (1992) 341-374, North-Holland.
44// http://www.springerlink.com/content/q645w3t2q229m248/
45//
46// Achim Koberstein, "The dual simplex method, techniques for a fast and stable
47// implementation", PhD, Paderborn, Univ., 2005.
48// http://digital.ub.uni-paderborn.de/hs/download/pdf/3885?originalFilename=true
50 public:
51 // Takes references to the linear program data we need.
52 explicit DualEdgeNorms(const BasisFactorization& basis_factorization);
53
54 // This type is neither copyable nor movable.
55 DualEdgeNorms(const DualEdgeNorms&) = delete;
57
58 // Clears, i.e. reset the object to its initial value. This will trigger a
59 // full norm recomputation on the next GetEdgeSquaredNorms().
60 void Clear();
61
62 // When we just add new constraints to the matrix and use an incremental
63 // solve, we do not need to recompute the norm of the old rows, and the norm
64 // of the new ones can be just set to 1 as long as we use identity columns for
65 // these.
66 void ResizeOnNewRows(RowIndex new_size);
67
68 // If this is true, then the caller must re-factorize the basis before the
69 // next call to GetEdgeSquaredNorms(). This is because the latter will
70 // recompute the norms from scratch and therefore needs a hightened precision
71 // and speed. This also indicates if GetEdgeSquaredNorms() will trigger a
72 // recomputation.
73 bool NeedsBasisRefactorization() const;
74
75 // Returns the dual edge squared norms. This is only valid if the caller
76 // properly called UpdateBeforeBasisPivot() before each basis pivot, or just
77 // called Clear().
79
80 // Updates the norms if the columns of the basis where permuted.
82
83 // Computes exactly the norm of the given leaving row, and returns true if it
84 // is good enough compared to our current norm. In both case update the
85 // current norm with its precise version and decide if we should recompute
86 // norms on the next GetEdgeSquaredNorms().
87 bool TestPrecision(RowIndex leaving_row,
88 const ScatteredRow& unit_row_left_inverse);
89
90 // Updates the norms just before a basis pivot is applied:
91 // - The column at leaving_row will leave the basis and the column at
92 // entering_col will enter it.
93 // - direction is the right inverse of the entering column.
94 // - unit_row_left_inverse is the left inverse of the unit row with index
95 // given by the leaving_row. This is also the leaving dual edge.
96 void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row,
97 const ScatteredColumn& direction,
98 const ScatteredRow& unit_row_left_inverse);
99
100 // Sets the algorithm parameters.
101 void SetParameters(const GlopParameters& parameters) {
102 parameters_ = parameters;
103 }
104
105 // Stats related functions.
106 std::string StatString() const { return stats_.StatString(); }
107
108 private:
109 // Recomputes the dual edge squared norms from scratch with maximum precision.
110 // The matrix must have been refactorized before because we will do a lot of
111 // inversions. See NeedsBasisRefactorization(). This is checked in debug mode.
112 void ComputeEdgeSquaredNorms();
113
114 // Computes the vector tau needed to update the norms using a right solve:
115 // B.tau = (u_i)^T, u_i.B = e_i for i = leaving_row.
116 const DenseColumn& ComputeTau(const ScatteredColumn& unit_row_left_inverse);
117
118 // Statistics.
119 struct Stats : public StatsGroup {
120 Stats()
121 : StatsGroup("DualEdgeNorms"),
122 tau_density("tau_density", this),
123 edge_norms_accuracy("edge_norms_accuracy", this),
124 lower_bounded_norms("lower_bounded_norms", this) {}
125 RatioDistribution tau_density;
126 DoubleDistribution edge_norms_accuracy;
127 IntegerDistribution lower_bounded_norms;
128 };
129 Stats stats_;
130
131 // Parameters.
132 GlopParameters parameters_;
133
134 // Problem data that should be updated from outside.
135 const BasisFactorization& basis_factorization_;
136
137 // The dual edge norms.
138 DenseColumn edge_squared_norms_;
139 DenseColumn tmp_edge_squared_norms_;
140
141 // Whether we should recompute the norm from scratch.
142 bool recompute_edge_squared_norms_;
143};
144
145} // namespace glop
146} // namespace operations_research
147
148#endif // OR_TOOLS_GLOP_DUAL_EDGE_NORMS_H_
Statistic on the distribution of a sequence of doubles.
Definition stats.h:276
Statistic on the distribution of a sequence of integers.
Definition stats.h:288
Statistic on the distribution of a sequence of ratios, displayed as %.
Definition stats.h:265
Base class to print a nice summary of a group of statistics.
Definition stats.h:128
std::string StatString() const
Definition stats.cc:77
DenseColumn::ConstView GetEdgeSquaredNorms()
DualEdgeNorms & operator=(const DualEdgeNorms &)=delete
std::string StatString() const
Stats related functions.
DualEdgeNorms(const BasisFactorization &basis_factorization)
Takes references to the linear program data we need.
void UpdateDataOnBasisPermutation(const ColumnPermutation &col_perm)
Updates the norms if the columns of the basis where permuted.
DualEdgeNorms(const DualEdgeNorms &)=delete
This type is neither copyable nor movable.
void UpdateBeforeBasisPivot(ColIndex entering_col, RowIndex leaving_row, const ScatteredColumn &direction, const ScatteredRow &unit_row_left_inverse)
void SetParameters(const GlopParameters &parameters)
Sets the algorithm parameters.
bool TestPrecision(RowIndex leaving_row, const ScatteredRow &unit_row_left_inverse)
SatParameters parameters
StrictITIVector< RowIndex, Fractional > DenseColumn
Column-vector types. Column-vector types are indexed by a row index.
Definition lp_types.h:382
In SWIG mode, we don't want anything besides these top-level includes.