OR-Tools  9.6
lp_types.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 // Common types and constants used by the Linear Programming solver.
15 
16 #ifndef OR_TOOLS_LP_DATA_LP_TYPES_H_
17 #define OR_TOOLS_LP_DATA_LP_TYPES_H_
18 
19 #include <cmath>
20 #include <cstdint>
21 #include <limits>
22 #include <ostream>
23 #include <string>
24 #include <type_traits>
25 #include <vector>
26 
28 #include "ortools/base/logging.h"
30 #include "ortools/util/bitset.h"
32 
33 // We use typedefs as much as possible to later permit the usage of
34 // types such as quad-doubles or rationals.
35 
36 namespace operations_research {
37 namespace glop {
38 
39 // This type is defined to avoid cast issues during index conversions,
40 // e.g. converting ColIndex into RowIndex.
41 // All types should use 'Index' instead of int32_t.
42 typedef int32_t Index;
43 
44 // ColIndex is the type for integers representing column/variable indices.
45 // int32s are enough for handling even the largest problems.
47 
48 // RowIndex is the type for integers representing row/constraint indices.
49 // int32s are enough for handling even the largest problems.
51 
52 // Get the ColIndex corresponding to the column # row.
53 inline ColIndex RowToColIndex(RowIndex row) { return ColIndex(row.value()); }
54 
55 // Get the RowIndex corresponding to the row # col.
56 inline RowIndex ColToRowIndex(ColIndex col) { return RowIndex(col.value()); }
57 
58 // Get the integer index corresponding to the col.
59 inline Index ColToIntIndex(ColIndex col) { return col.value(); }
60 
61 // Get the integer index corresponding to the row.
62 inline Index RowToIntIndex(RowIndex row) { return row.value(); }
63 
64 // EntryIndex is the type for integers representing entry indices.
65 // An entry in a sparse matrix is a pair (row, value) for a given known column.
66 // See classes SparseColumn and SparseMatrix.
67 #if defined(__ANDROID__)
68 DEFINE_STRONG_INDEX_TYPE(EntryIndex);
69 #else
71 #endif
72 
73 static inline double ToDouble(double f) { return f; }
74 
75 static inline double ToDouble(long double f) { return static_cast<double>(f); }
76 
77 // The type Fractional denotes the type of numbers on which the computations are
78 // performed. This is defined as double here, but it could as well be float,
79 // DoubleDouble, QuadDouble, or infinite-precision rationals.
80 // Floating-point representations are binary fractional numbers, thus the name.
81 // (See http://en.wikipedia.org/wiki/Fraction_(mathematics) .)
82 typedef double Fractional;
83 
84 // Range max for type Fractional. DBL_MAX for double for example.
86 
87 // Infinity for type Fractional.
88 constexpr double kInfinity = std::numeric_limits<double>::infinity();
89 
90 // Epsilon for type Fractional, i.e. the smallest e such that 1.0 + e != 1.0 .
91 constexpr double kEpsilon = std::numeric_limits<double>::epsilon();
92 
93 // Returns true if the given value is finite, that means for a double:
94 // not a NaN and not +/- infinity.
95 inline bool IsFinite(Fractional value) {
96  return value > -kInfinity && value < kInfinity;
97 }
98 
99 // Constants to represent invalid row or column index.
100 // It is important that their values be the same because during transposition,
101 // one needs to be converted into the other.
102 constexpr RowIndex kInvalidRow(-1);
103 constexpr ColIndex kInvalidCol(-1);
104 
105 // Different statuses for a given problem.
106 enum class ProblemStatus : int8_t {
107  // The problem has been solved to optimality. Both the primal and dual have
108  // a feasible solution.
109  OPTIMAL,
110 
111  // The problem has been proven primal-infeasible. Note that the problem is not
112  // necessarily DUAL_UNBOUNDED (See Chvatal p.60). The solver does not have a
113  // dual unbounded ray in this case.
115 
116  // The problem has been proven dual-infeasible. Note that the problem is not
117  // necessarily PRIMAL_UNBOUNDED (See Chvatal p.60). The solver does
118  // note have a primal unbounded ray in this case,
120 
121  // The problem is either INFEASIBLE or UNBOUNDED (this applies to both the
122  // primal and dual algorithms). This status is only returned by the presolve
123  // step and means that a primal or dual unbounded ray was found during
124  // presolve. Note that because some presolve techniques assume that a feasible
125  // solution exists to simplify the problem further, it is difficult to
126  // distinguish between infeasibility and unboundedness.
127  //
128  // If a client needs to distinguish, it is possible to run the primal
129  // algorithm on the same problem with a 0 objective function to know if the
130  // problem was PRIMAL_INFEASIBLE.
132 
133  // The problem has been proven feasible and unbounded. That means that the
134  // problem is DUAL_INFEASIBLE and that the solver has a primal unbounded ray.
136 
137  // The problem has been proven dual-feasible and dual-unbounded. That means
138  // the problem is PRIMAL_INFEASIBLE and that the solver has a dual unbounded
139  // ray to prove it.
141 
142  // All the statuses below correspond to a case where the solver was
143  // interrupted. This can happen because of a timeout, an iteration limit or an
144  // error.
145 
146  // The solver didn't had a chance to prove anything.
147  INIT,
148 
149  // The problem has been proven primal-feasible but may still be
150  // PRIMAL_UNBOUNDED.
152 
153  // The problem has been proven dual-feasible, but may still be DUAL_UNBOUNDED.
154  // That means that if the primal is feasible, then it has a finite optimal
155  // solution.
157 
158  // An error occurred during the solving process.
159  ABNORMAL,
160 
161  // The input problem was invalid (see LinearProgram.IsValid()).
163 
164  // The problem was solved to a feasible status, but the solution checker found
165  // the primal and/or dual infeasibilities too important for the specified
166  // parameters.
167  IMPRECISE,
168 };
169 
170 // Returns the string representation of the ProblemStatus enum.
171 std::string GetProblemStatusString(ProblemStatus problem_status);
172 
173 inline std::ostream& operator<<(std::ostream& os, ProblemStatus status) {
175  return os;
176 }
177 
178 // Different types of variables.
179 enum class VariableType : int8_t {
185 };
186 
187 // Returns the string representation of the VariableType enum.
188 std::string GetVariableTypeString(VariableType variable_type);
189 
190 inline std::ostream& operator<<(std::ostream& os, VariableType type) {
191  os << GetVariableTypeString(type);
192  return os;
193 }
194 
195 // Different variables statuses.
196 // If a solution is OPTIMAL or FEASIBLE, then all the properties described here
197 // should be satisfied. These properties should also be true during the
198 // execution of the revised simplex algorithm, except that because of
199 // bound-shifting, the variable may not be at their exact bounds until the
200 // shifts are removed.
201 enum class VariableStatus : int8_t {
202  // The basic status is special and takes precedence over all the other
203  // statuses. It means that the variable is part of the basis.
204  BASIC,
205  // Only possible status of a FIXED_VARIABLE not in the basis. The variable
206  // value should be exactly equal to its bounds (which are the same).
207  FIXED_VALUE,
208  // Only possible statuses of a non-basic variable which is not UNCONSTRAINED
209  // or FIXED. The variable value should be at its exact specified bound (which
210  // must be finite).
213  // Only possible status of an UNCONSTRAINED non-basic variable.
214  // Its value should be zero.
215  //
216  // Note that during crossover, this status is relaxed, and any variable that
217  // can currently move in both directions can be marked as free.
218  FREE,
219 };
220 
221 // Returns the string representation of the VariableStatus enum.
223 
224 inline std::ostream& operator<<(std::ostream& os, VariableStatus status) {
226  return os;
227 }
228 
229 // Different constraints statuses.
230 // The meaning is the same for the constraint activity relative to its bounds as
231 // it is for a variable value relative to its bounds. Actually, this is the
232 // VariableStatus of the slack variable associated to a constraint modulo a
233 // change of sign. The difference is that because of precision error, a
234 // constraint activity cannot exactly be equal to one of its bounds or to zero.
235 enum class ConstraintStatus : int8_t {
236  BASIC,
237  FIXED_VALUE,
240  FREE,
241 };
242 
243 // Returns the string representation of the ConstraintStatus enum.
245 
246 inline std::ostream& operator<<(std::ostream& os, ConstraintStatus status) {
248  return os;
249 }
250 
251 // Returns the ConstraintStatus corresponding to a given VariableStatus.
253 
254 // A span of `T`, indexed by a strict int type `IntType`. Intended to be passed
255 // by value. See b/259677543.
256 template <typename IntType, typename T>
258  public:
259  using IndexType = IntType;
260  using reference = T&;
261  using value_type = T;
262 
263  StrictITISpan(T* data, IntType size) : data_(data), size_(size) {}
264 
265  reference operator[](IntType i) const {
266  return data_[static_cast<size_t>(i.value())];
267  }
268 
269  IntType size() const { return size_; }
270 
271  // TODO(user): This should probably be a strictly typed iterator too, but
272  // `StrongVector::begin()` already suffers from this problem.
273  auto begin() const { return data_; }
274  auto end() const { return data_ + static_cast<size_t>(size_.value()); }
275 
276  private:
277  T* const data_;
278  const IntType size_;
279 };
280 
281 // Wrapper around an ITIVector to allow (and enforce) creation/resize/assign
282 // to use the index type for the size.
283 //
284 // TODO(user): This should probably move into ITIVector, but note that this
285 // version is more strict and does not allow any other size types.
286 template <typename IntType, typename T>
287 class StrictITIVector : public absl::StrongVector<IntType, T> {
288  public:
289  typedef IntType IndexType;
293 
294 // This allows for brace initialization, which is really useful in tests.
295 // It is not 'explicit' by design, so one can do vector = {...};
296 #if !defined(__ANDROID__) && (!defined(_MSC_VER) || (_MSC_VER >= 1800))
297  StrictITIVector(std::initializer_list<T> init_list) // NOLINT
298  : ParentType(init_list.begin(), init_list.end()) {}
299 #endif
301  explicit StrictITIVector(IntType size) : ParentType(size.value()) {}
302  StrictITIVector(IntType size, const T& v) : ParentType(size.value(), v) {}
303  template <typename InputIteratorType>
304  StrictITIVector(InputIteratorType first, InputIteratorType last)
305  : ParentType(first, last) {}
306 
307  void resize(IntType size) { ParentType::resize(size.value()); }
308  void resize(IntType size, const T& v) { ParentType::resize(size.value(), v); }
309 
310  void reserve(IntType size) { ParentType::reserve(size.value()); }
311 
312  void assign(IntType size, const T& v) { ParentType::assign(size.value(), v); }
313 
314  IntType size() const { return IntType(ParentType::size()); }
315 
316  IntType capacity() const { return IntType(ParentType::capacity()); }
317 
318  View view() { return View(ParentType::data(), size()); }
320  ConstView view() const { return const_view(); }
321 
322  // Since calls to resize() must use a default value, we introduce a new
323  // function for convenience to reduce the size of a vector.
324  void resize_down(IntType size) {
325  DCHECK_GE(size, IntType(0));
326  DCHECK_LE(size, IntType(ParentType::size()));
327  ParentType::resize(size.value());
328  }
329 
330  // This function can be up to 4 times faster than calling assign(size, 0).
331  // Note that it only works with StrictITIVector of basic types.
332  void AssignToZero(IntType size) {
333  resize(size, 0);
334  memset(ParentType::data(), 0, size.value() * sizeof(T));
335  }
336 };
337 
338 // Row-vector types. Row-vector types are indexed by a column index.
339 
340 // Row of fractional values.
342 
343 // Row of booleans.
345 
346 // Row of column indices. Used to represent mappings between columns.
348 
349 // Vector of row or column indices. Useful to list the non-zero positions.
350 typedef std::vector<ColIndex> ColIndexVector;
351 typedef std::vector<RowIndex> RowIndexVector;
352 
353 // Row of row indices.
354 // Useful for knowing which row corresponds to a particular column in the basis,
355 // or for storing the number of rows for a given column.
357 
358 // Row of variable types.
360 
361 // Row of variable statuses.
363 
364 // Row of bits.
366 
367 // Column-vector types. Column-vector types are indexed by a row index.
368 
369 // Column of fractional values.
371 
372 // Column of booleans.
374 
375 // Column of bits.
377 
378 // Column of row indices. Used to represent mappings between rows.
380 
381 // Column of column indices.
382 // Used to represent which column corresponds to a particular row in the basis,
383 // or for storing the number of columns for a given row.
385 
386 // Column of constraints (slack variables) statuses.
388 
389 // --------------------------------------------------------
390 // VectorIterator
391 // --------------------------------------------------------
392 
393 // An iterator over the elements of a sparse data structure that stores the
394 // elements in arrays for indices and coefficients. The iterator is
395 // built as a wrapper over a sparse vector entry class; the concrete entry class
396 // is provided through the template argument EntryType.
397 template <typename EntryType>
398 class VectorIterator : EntryType {
399  public:
400  using Index = typename EntryType::Index;
401  using Entry = EntryType;
402 
403  VectorIterator(const Index* indices, const Fractional* coefficients,
404  EntryIndex i)
405  : EntryType(indices, coefficients, i) {}
406 
407  void operator++() { ++this->i_; }
408  bool operator!=(const VectorIterator& other) const {
409  // This operator is intended for use in natural range iteration ONLY.
410  // Therefore, we prefer to use '<' so that a buggy range iteration which
411  // start point is *after* its end point stops immediately, instead of
412  // iterating 2^(number of bits of EntryIndex) times.
413  return this->i_ < other.i_;
414  }
415  const Entry& operator*() const { return *this; }
416 };
417 
418 // This is used during the deterministic time computation to convert a given
419 // number of floating-point operations to something in the same order of
420 // magnitude as a second (on a 2014 desktop).
421 static inline double DeterministicTimeForFpOperations(int64_t n) {
422  const double kConversionFactor = 2e-9;
423  return kConversionFactor * static_cast<double>(n);
424 }
425 
426 } // namespace glop
427 } // namespace operations_research
428 
429 #endif // OR_TOOLS_LP_DATA_LP_TYPES_H_
int64_t max
Definition: alldiff_cst.cc:140
void assign(size_type n, const value_type &val)
void resize(size_type new_size)
void reserve(size_type n)
size_type size() const
size_type capacity() const
std::vector< T, Alloc > ParentType
Definition: strong_vector.h:79
reference operator[](IntType i) const
Definition: lp_types.h:265
StrictITISpan(T *data, IntType size)
Definition: lp_types.h:263
StrictITIVector(InputIteratorType first, InputIteratorType last)
Definition: lp_types.h:304
StrictITISpan< IntType, T > View
Definition: lp_types.h:291
StrictITIVector(std::initializer_list< T > init_list)
Definition: lp_types.h:297
void resize(IntType size, const T &v)
Definition: lp_types.h:308
StrictITISpan< IntType, const T > ConstView
Definition: lp_types.h:292
StrictITIVector(IntType size, const T &v)
Definition: lp_types.h:302
void assign(IntType size, const T &v)
Definition: lp_types.h:312
absl::StrongVector< IntType, T > ParentType
Definition: lp_types.h:290
typename EntryType::Index Index
Definition: lp_types.h:400
bool operator!=(const VectorIterator &other) const
Definition: lp_types.h:408
VectorIterator(const Index *indices, const Fractional *coefficients, EntryIndex i)
Definition: lp_types.h:403
int64_t value
absl::Status status
Definition: g_gurobi.cc:41
absl::Span< const double > coefficients
ColIndex col
Definition: markowitz.cc:186
RowIndex row
Definition: markowitz.cc:185
constexpr ColIndex kInvalidCol(-1)
Bitset64< RowIndex > DenseBitColumn
Definition: lp_types.h:376
std::vector< ColIndex > ColIndexVector
Definition: lp_types.h:350
constexpr double kEpsilon
Definition: lp_types.h:91
StrictITIVector< ColIndex, VariableType > VariableTypeRow
Definition: lp_types.h:359
StrictITIVector< ColIndex, Fractional > DenseRow
Definition: lp_types.h:341
std::string GetProblemStatusString(ProblemStatus problem_status)
Definition: lp_types.cc:21
DEFINE_STRONG_INDEX_TYPE(ColIndex)
DEFINE_STRONG_INT64_TYPE(EntryIndex)
Index ColToIntIndex(ColIndex col)
Definition: lp_types.h:59
constexpr double kInfinity
Definition: lp_types.h:88
std::string GetConstraintStatusString(ConstraintStatus status)
Definition: lp_types.cc:92
StrictITIVector< ColIndex, VariableStatus > VariableStatusRow
Definition: lp_types.h:362
constexpr double kRangeMax
Definition: lp_types.h:85
std::ostream & operator<<(std::ostream &os, ProblemStatus status)
Definition: lp_types.h:173
StrictITIVector< RowIndex, RowIndex > RowMapping
Definition: lp_types.h:379
StrictITIVector< RowIndex, ConstraintStatus > ConstraintStatusColumn
Definition: lp_types.h:387
ColIndex RowToColIndex(RowIndex row)
Definition: lp_types.h:53
bool IsFinite(Fractional value)
Definition: lp_types.h:95
constexpr RowIndex kInvalidRow(-1)
Bitset64< ColIndex > DenseBitRow
Definition: lp_types.h:365
RowIndex ColToRowIndex(ColIndex col)
Definition: lp_types.h:56
ConstraintStatus VariableToConstraintStatus(VariableStatus status)
Definition: lp_types.cc:111
std::vector< RowIndex > RowIndexVector
Definition: lp_types.h:351
StrictITIVector< ColIndex, bool > DenseBooleanRow
Definition: lp_types.h:344
StrictITIVector< ColIndex, RowIndex > ColToRowMapping
Definition: lp_types.h:356
StrictITIVector< RowIndex, ColIndex > RowToColMapping
Definition: lp_types.h:384
std::string GetVariableTypeString(VariableType variable_type)
Definition: lp_types.cc:54
StrictITIVector< RowIndex, Fractional > DenseColumn
Definition: lp_types.h:370
StrictITIVector< RowIndex, bool > DenseBooleanColumn
Definition: lp_types.h:373
static double DeterministicTimeForFpOperations(int64_t n)
Definition: lp_types.h:421
std::string GetVariableStatusString(VariableStatus status)
Definition: lp_types.cc:73
Index RowToIntIndex(RowIndex row)
Definition: lp_types.h:62
StrictITIVector< ColIndex, ColIndex > ColMapping
Definition: lp_types.h:347
static double ToDouble(double f)
Definition: lp_types.h:73
Collection of objects used to extend the Constraint Solver library.