OR-Tools  8.1
cp_model_presolve.h
Go to the documentation of this file.
1 // Copyright 2010-2018 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_SAT_CP_MODEL_PRESOLVE_H_
15 #define OR_TOOLS_SAT_CP_MODEL_PRESOLVE_H_
16 
17 #include <vector>
18 
25 #include "ortools/util/bitset.h"
28 
29 namespace operations_research {
30 namespace sat {
31 
32 // Replaces all the instance of a variable i (and the literals referring to it)
33 // by mapping[i]. The definition of variables i is also moved to its new index.
34 // Variables with a negative mapping value are ignored and it is an error if
35 // such variable is referenced anywhere (this is CHECKed).
36 //
37 // The image of the mapping should be dense in [0, new_num_variables), this is
38 // also CHECKed.
39 void ApplyVariableMapping(const std::vector<int>& mapping,
40  const PresolveContext& context);
41 
42 // Presolves the initial content of presolved_model.
43 //
44 // This also creates a mapping model that encode the correspondence between the
45 // two problems. This works as follow:
46 // - The first variables of mapping_model are in one to one correspondence with
47 // the variables of the initial model.
48 // - The presolved_model variables are in one to one correspondence with the
49 // variable at the indices given by postsolve_mapping in the mapping model.
50 // - Fixing one of the two sets of variables and solving the model will assign
51 // the other set to a feasible solution of the other problem. Moreover, the
52 // objective value of these solutions will be the same. Note that solving such
53 // problems will take little time in practice because the propagation will
54 // basically do all the work.
55 //
56 // Note(user): an optimization model can be transformed into a decision problem,
57 // if for instance the objective is fixed, or independent from the rest of the
58 // problem.
59 //
60 // TODO(user): Identify disconnected components and returns a vector of
61 // presolved model? If we go this route, it may be nicer to store the indices
62 // inside the model. We can add a IntegerVariableProto::initial_index;
64  public:
66  std::vector<int>* postsolve_mapping);
67 
68  // Returns false if a non-recoverable error was encountered.
69  //
70  // TODO(user): Make sure this can never run into this case provided that the
71  // initial model is valid!
72  bool Presolve();
73 
74  // Executes presolve method for the given constraint. Public for testing only.
75  bool PresolveOneConstraint(int c);
76 
77  // Public for testing only.
79 
80  private:
81  void PresolveToFixPoint();
82 
83  // Runs the probing.
84  void Probe();
85 
86  // Presolve functions.
87  //
88  // They should return false only if the constraint <-> variable graph didn't
89  // change. This is just an optimization, returning true is always correct.
90  //
91  // Invariant about UNSAT: All these functions should abort right away if
92  // context_.IsUnsat() is true. And the only way to change the status to unsat
93  // is through ABSL_MUST_USE_RESULT function that should also abort right away
94  // the current code. This way we shouldn't keep doing computation on an
95  // inconsistent state.
96  // TODO(user,user): Make these public and unit test.
97  bool PresolveAutomaton(ConstraintProto* ct);
98  bool PresolveCircuit(ConstraintProto* ct);
99  bool PresolveRoutes(ConstraintProto* ct);
100  bool PresolveCumulative(ConstraintProto* ct);
101  bool PresolveNoOverlap(ConstraintProto* ct);
102  bool PresolveAllDiff(ConstraintProto* ct);
103  bool PresolveTable(ConstraintProto* ct);
104  bool PresolveElement(ConstraintProto* ct);
105  bool PresolveInterval(int c, ConstraintProto* ct);
106  bool PresolveIntDiv(ConstraintProto* ct);
107  bool PresolveIntProd(ConstraintProto* ct);
108  bool PresolveIntMin(ConstraintProto* ct);
109  bool PresolveIntMax(ConstraintProto* ct);
110  bool PresolveLinMin(ConstraintProto* ct);
111  bool PresolveLinMax(ConstraintProto* ct);
112  bool PresolveIntAbs(ConstraintProto* ct);
113  bool PresolveBoolXor(ConstraintProto* ct);
114  bool PresolveAtMostOne(ConstraintProto* ct);
115  bool PresolveBoolAnd(ConstraintProto* ct);
116  bool PresolveBoolOr(ConstraintProto* ct);
117  bool PresolveEnforcementLiteral(ConstraintProto* ct);
118 
119  // For the linear constraints, we have more than one function.
120  bool CanonicalizeLinear(ConstraintProto* ct);
121  bool PropagateDomainsInLinear(int c, ConstraintProto* ct);
122  bool RemoveSingletonInLinear(ConstraintProto* ct);
123  bool PresolveSmallLinear(ConstraintProto* ct);
124  bool PresolveLinearOnBooleans(ConstraintProto* ct);
125  void PresolveLinearEqualityModuloTwo(ConstraintProto* ct);
126 
127  // SetPPC is short for set packing, partitioning and covering constraints.
128  // These are sum of booleans <=, = and >= 1 respectively.
129  bool ProcessSetPPC();
130 
131  // Removes dominated constraints or fixes some variables for given pair of
132  // setppc constraints. This assumes that literals in constraint c1 is subset
133  // of literals in constraint c2.
134  bool ProcessSetPPCSubset(int c1, int c2, const std::vector<int>& c2_minus_c1,
135  const std::vector<int>& original_constraint_index,
136  std::vector<bool>* marked_for_removal);
137 
138  void PresolvePureSatPart();
139 
140  // Extracts AtMostOne constraint from Linear constraint.
141  void ExtractAtMostOneFromLinear(ConstraintProto* ct);
142 
143  void DivideLinearByGcd(ConstraintProto* ct);
144 
145  void ExtractEnforcementLiteralFromLinearConstraint(int ct_index,
146  ConstraintProto* ct);
147 
148  // Extracts cliques from bool_and and small at_most_one constraints and
149  // transforms them into maximal cliques.
150  void TransformIntoMaxCliques();
151 
152  // Converts bool_or and at_most_one of size 2 to bool_and.
153  void ExtractBoolAnd();
154 
155  void ExpandObjective();
156 
157  void TryToSimplifyDomain(int var);
158 
159  void MergeNoOverlapConstraints();
160 
161  // Boths function are responsible for dealing with affine relations.
162  // The second one returns false on UNSAT.
163  void EncodeAllAffineRelations();
164  bool PresolveAffineRelationIfAny(int var);
165 
166  bool IntervalsCanIntersect(const IntervalConstraintProto& interval1,
167  const IntervalConstraintProto& interval2);
168 
169  bool ExploitEquivalenceRelations(int c, ConstraintProto* ct);
170 
171  ABSL_MUST_USE_RESULT bool RemoveConstraint(ConstraintProto* ct);
172  ABSL_MUST_USE_RESULT bool MarkConstraintAsFalse(ConstraintProto* ct);
173 
174  const PresolveOptions& options_;
175  std::vector<int>* postsolve_mapping_;
176  PresolveContext* context_;
177 
178  // Used by CanonicalizeLinear().
179  std::vector<std::pair<int, int64>> tmp_terms_;
180 };
181 
182 // Convenient wrapper to call the full presolve.
184  std::vector<int>* postsolve_mapping);
185 
186 // Returns the index of exact duplicate constraints in the given proto. That
187 // is, all returned constraints will have an identical constraint before it in
188 // the model_proto.constraints() list. Empty constraints are ignored.
189 //
190 // Visible here for testing. This is meant to be called at the end of the
191 // presolve where constraints have been canonicalized.
192 //
193 // TODO(user): Ignore names? canonicalize constraint further by sorting
194 // enforcement literal list for instance...
195 std::vector<int> FindDuplicateConstraints(const CpModelProto& model_proto);
196 
197 } // namespace sat
198 } // namespace operations_research
199 
200 #endif // OR_TOOLS_SAT_CP_MODEL_PRESOLVE_H_
var
IntVar * var
Definition: expr_array.cc:1858
cp_model.pb.h
time_limit.h
operations_research::sat::PresolveCpModel
bool PresolveCpModel(const PresolveOptions &options, PresolveContext *context, std::vector< int > *postsolve_mapping)
Definition: cp_model_presolve.cc:4699
presolve_context.h
operations_research::sat::PresolveOptions
Definition: presolve_context.h:37
model_proto
CpModelProto const * model_proto
Definition: cp_model_solver.cc:2081
operations_research::sat::CpModelPresolver::Presolve
bool Presolve()
Definition: cp_model_presolve.cc:4751
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
operations_research::sat::CpModelPresolver::PresolveOneConstraint
bool PresolveOneConstraint(int c)
Definition: cp_model_presolve.cc:4036
context
GurobiMPCallbackContext * context
Definition: gurobi_interface.cc:509
presolve_util.h
sat_parameters.pb.h
ct
const Constraint * ct
Definition: demon_profiler.cc:42
operations_research::sat::FindDuplicateConstraints
std::vector< int > FindDuplicateConstraints(const CpModelProto &model_proto)
Definition: cp_model_presolve.cc:5136
operations_research::sat::CpModelPresolver::RemoveEmptyConstraints
void RemoveEmptyConstraints()
Definition: cp_model_presolve.cc:61
sorted_interval_list.h
operations_research::sat::PresolveContext
Definition: presolve_context.h:72
operations_research::sat::CpModelPresolver
Definition: cp_model_presolve.h:63
affine_relation.h
operations_research::sat::ApplyVariableMapping
void ApplyVariableMapping(const std::vector< int > &mapping, const PresolveContext &context)
Definition: cp_model_presolve.cc:5035
operations_research::sat::CpModelPresolver::CpModelPresolver
CpModelPresolver(const PresolveOptions &options, PresolveContext *context, std::vector< int > *postsolve_mapping)
Definition: cp_model_presolve.cc:4705
bitset.h
cp_model_utils.h