Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
presolve.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_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/types.h"
31
32namespace operations_research {
33namespace 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.
38class 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),
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 PresolveInt2Float(Constraint* ct);
99 void PresolveStoreAffineMapping(Constraint* ct);
100 void PresolveStoreFlatteningMapping(Constraint* ct);
101 void PresolveSimplifyElement(Constraint* ct);
102 void PresolveSimplifyExprElement(Constraint* ct);
103
104 // Helpers.
105 void UpdateRuleStats(const std::string& rule_name) {
106 successful_rules_[rule_name]++;
107 }
108
109 // The presolver will discover some equivalence classes of variables [two
110 // variable are equivalent when replacing one by the other leads to the same
111 // logical model]. We will store them here, using a Union-find data structure.
112 // See http://en.wikipedia.org/wiki/Disjoint-set_data_structure.
113 // Note that the equivalence is directed. We prefer to replace all instances
114 // of 'from' with 'to', rather than the opposite.
115 void AddVariableSubstitution(Variable* from, Variable* to);
116 Variable* FindRepresentativeOfVar(Variable* var);
117 absl::flat_hash_map<const Variable*, Variable*> var_representative_map_;
118 std::vector<Variable*> var_representative_vector_;
119
120 // Stores affine_map_[x] = a * y + b.
121 absl::flat_hash_map<const Variable*, AffineMapping> affine_map_;
122
123 // Stores array2d_index_map_[z] = a * x + y + b.
124 absl::flat_hash_map<const Variable*, Array2DIndexMapping> array2d_index_map_;
125
126 // Count applications of presolve rules. Use a sorted map for reporting
127 // purposes.
128 std::map<std::string, int> successful_rules_;
129
130 SolverLogger* logger_;
131};
132} // namespace fz
133} // namespace operations_research
134
135#endif // OR_TOOLS_FLATZINC_PRESOLVE_H_
Presolver(SolverLogger *logger)
Definition presolve.h:40
const Constraint * ct
IntVar * var
GRBmodel * model
In SWIG mode, we don't want anything besides these top-level includes.
trees with all degrees equal to
int64_t coefficient