OR-Tools  9.3
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"
29
30namespace operations_research {
31namespace 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.
36class 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_
A constraint is the main modeling object.
Presolver(SolverLogger *logger)
Definition: presolve.h:38
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