OR-Tools  9.6
presolve.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 #ifndef OR_TOOLS_FLATZINC_PRESOLVE_H_
15 #define OR_TOOLS_FLATZINC_PRESOLVE_H_
16 
17 #include <cstdint>
18 #include <functional>
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 #include "absl/container/flat_hash_map.h"
24 #include "absl/container/flat_hash_set.h"
25 #include "absl/strings/match.h"
26 #include "ortools/base/hash.h"
28 #include "ortools/base/logging.h"
29 #include "ortools/flatzinc/model.h"
30 #include "ortools/util/logging.h"
31 
32 namespace operations_research {
33 namespace fz {
34 // The Presolver "pre-solves" a Model by applying some iterative
35 // transformations to it, which may simplify and/or shrink the model.
36 //
37 // TODO(user): Error reporting of unfeasible models.
38 class Presolver {
39  public:
40  explicit Presolver(SolverLogger* logger) : logger_(logger) {}
41  // Recursively apply all the pre-solve rules to the model, until exhaustion.
42  // The reduced model will:
43  // - Have some unused variables.
44  // - Have some unused constraints (marked as inactive).
45  // - Have some modified constraints (for example, they will no longer
46  // refer to unused variables).
47  void Run(Model* model);
48 
49  private:
50  // This struct stores the affine mapping of one variable:
51  // it represents new_var = var * coefficient + offset. It also stores the
52  // constraint that defines this mapping.
53  struct AffineMapping {
54  Variable* variable;
55  int64_t coefficient;
56  int64_t offset;
57  Constraint* constraint;
58 
59  AffineMapping()
60  : variable(nullptr), coefficient(0), offset(0), constraint(nullptr) {}
61  AffineMapping(Variable* v, int64_t c, int64_t o, Constraint* ct)
62  : variable(v), coefficient(c), offset(o), constraint(ct) {}
63  };
64 
65  // This struct stores the mapping of two index variables (of a 2D array; not
66  // included here) onto a single index variable (of the flattened 1D array).
67  // The original 2D array could be trimmed in the process; so we also need an
68  // offset.
69  // Eg. new_index_var = index_var1 * int_coeff + index_var2 + int_offset
70  struct Array2DIndexMapping {
71  Variable* variable1;
72  int64_t coefficient;
73  Variable* variable2;
74  int64_t offset;
75  Constraint* constraint;
76 
77  Array2DIndexMapping()
78  : variable1(nullptr),
79  coefficient(0),
80  variable2(nullptr),
81  offset(0),
82  constraint(nullptr) {}
83  Array2DIndexMapping(Variable* v1, int64_t c, Variable* v2, int64_t o,
84  Constraint* ct)
85  : variable1(v1),
86  coefficient(c),
87  variable2(v2),
88  offset(o),
89  constraint(ct) {}
90  };
91 
92  // Substitution support.
93  void SubstituteEverywhere(Model* model);
94  void SubstituteAnnotation(Annotation* ann);
95 
96  // Presolve rules.
97  void PresolveBool2Int(Constraint* ct);
98  void PresolveStoreAffineMapping(Constraint* ct);
99  void PresolveStoreFlatteningMapping(Constraint* ct);
100  void PresolveSimplifyElement(Constraint* ct);
101  void PresolveSimplifyExprElement(Constraint* ct);
102 
103  // Helpers.
104  void UpdateRuleStats(const std::string& rule_name) {
105  successful_rules_[rule_name]++;
106  }
107 
108  // The presolver will discover some equivalence classes of variables [two
109  // variable are equivalent when replacing one by the other leads to the same
110  // logical model]. We will store them here, using a Union-find data structure.
111  // See http://en.wikipedia.org/wiki/Disjoint-set_data_structure.
112  // Note that the equivalence is directed. We prefer to replace all instances
113  // of 'from' with 'to', rather than the opposite.
114  void AddVariableSubstitution(Variable* from, Variable* to);
115  Variable* FindRepresentativeOfVar(Variable* var);
116  absl::flat_hash_map<const Variable*, Variable*> var_representative_map_;
117  std::vector<Variable*> var_representative_vector_;
118 
119  // Stores affine_map_[x] = a * y + b.
120  absl::flat_hash_map<const Variable*, AffineMapping> affine_map_;
121 
122  // Stores array2d_index_map_[z] = a * x + y + b.
123  absl::flat_hash_map<const Variable*, Array2DIndexMapping> array2d_index_map_;
124 
125  // Count applications of presolve rules. Use a sorted map for reporting
126  // purposes.
127  std::map<std::string, int> successful_rules_;
128 
129  SolverLogger* logger_;
130 };
131 } // namespace fz
132 } // namespace operations_research
133 
134 #endif // OR_TOOLS_FLATZINC_PRESOLVE_H_
A constraint is the main modeling object.
Presolver(SolverLogger *logger)
Definition: presolve.h:40
const Constraint * ct
IntVar * var
Definition: expr_array.cc:1874
GRBmodel * model
Collection of objects used to extend the Constraint Solver library.
int64_t coefficient