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