Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
presolve_encoding.h
Go to the documentation of this file.
1// Copyright 2010-2025 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 ORTOOLS_SAT_PRESOLVE_ENCODING_H_
15#define ORTOOLS_SAT_PRESOLVE_ENCODING_H_
16
17#include <cstdint>
18#include <vector>
19
20#include "absl/container/flat_hash_map.h"
21#include "absl/container/flat_hash_set.h"
24
25namespace operations_research {
26namespace sat {
27
29 // The integer variable that is encoded. Internally it can be replaced by
30 // -1 if some presolve rule removed the variable.
31 int var;
32
33 // The linear1 constraint indexes that define conditional bounds on the
34 // variable. Those linear1 should have exactly one enforcement literal and
35 // satisfy `PositiveRef(enf) != var`. All linear1 restraining `var` and
36 // fulfilling the conditions above will appear here.
37 std::vector<int> linear1_constraints;
38
39 // Constraints of the form bool_or/exactly_one/at_most_one that contains at
40 // least two of the encoding booleans.
42
43 // Booleans that do not appear on any constraints outside the local model.
45
46 // Zero if `var` doesn't appear in the objective.
48
49 // Note: the objective doesn't count as a constraint outside the local model.
51
52 // Set to -1 if there is none or if the variable appears in more than one
53 // constraint outside the local model.
55};
56
57// For performance, this skips variables that appears in a single linear1 and is
58// used in more than another constraint, since there is no interesting presolve
59// we can do in this case.
60std::vector<VariableEncodingLocalModel> CreateVariableEncodingLocalModels(
61 PresolveContext* context);
62
63// Do a few simple presolve rules on the local model:
64// - restrict the domain of the linear1 to the domain of the variable.
65// - merge linear1 over the same enforcement,var pairs.
66// - if we have a linear1 for a literal and another for its negation, do
67// not allow both to be true.
68//
69// Also returns a list of literals that fully encodes a domain for the variable.
70// Returns false if we prove unsat.
72 PresolveContext* context, VariableEncodingLocalModel& local_model,
73 absl::flat_hash_map<int, Domain>* result, bool* changed);
74
75// If we have a model containing:
76// l1 => var in [0, 10]
77// ~l1 => var in [11, 20]
78// l2 => var in [50, 60]
79// ~l2 => var in [70, 80]
80// bool_or(l1, l2, ...)
81//
82// if moreover `l1` and `l2` are only used in the constraints above, we can
83// replace them by:
84// l3 => var in [0, 10] U [50, 60]
85// ~l3 => var in [11, 20] U [70, 80]
86// bool_or(l3, ...)
87//
88// and remove the variables `l1` and `l2`. This also works if we replace the
89// bool_or for an at_most_one or an exactly_one, but requires imposing
90// (unconditionally) that the variable cannot be both in the domain encoded by
91// `l1` and in the domain encoded by `l2`.
93 VariableEncodingLocalModel& local_model);
94
95// If we have a bunch of constraint of the form literal => Y \in domain and
96// another constraint Y = f(X), we can remove Y, that constraint, and transform
97// all linear1 from constraining Y to constraining X.
98//
99// We can for instance do it for Y = abs(X) or Y = X^2 easily. More complex
100// function might be trickier.
101//
102// Note that we can't always do it in the reverse direction though!
103// If we have l => X = -1, we can't transfer that to abs(X) for instance, since
104// X=1 will also map to abs(-1). We can only do it if for all implied domain D
105// we have f^-1(f(D)) = D, which is not easy to check.
106// Returns false if we prove unsat.
108 VariableEncodingLocalModel& local_model, PresolveContext* context);
109
110} // namespace sat
111} // namespace operations_research
112
113#endif // ORTOOLS_SAT_PRESOLVE_ENCODING_H_
std::vector< VariableEncodingLocalModel > CreateVariableEncodingLocalModels(PresolveContext *context)
bool BasicPresolveAndGetFullyEncodedDomains(PresolveContext *context, VariableEncodingLocalModel &local_model, absl::flat_hash_map< int, Domain > *result, bool *changed)
bool MaybeTransferLinear1ToAnotherVariable(VariableEncodingLocalModel &local_model, PresolveContext *context)
bool DetectAllEncodedComplexDomain(PresolveContext *context, VariableEncodingLocalModel &local_model)
OR-Tools root namespace.
absl::flat_hash_set< int > bools_only_used_inside_the_local_model