Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
cp_model_copy.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 OR_TOOLS_SAT_CP_MODEL_COPY_H_
15#define OR_TOOLS_SAT_CP_MODEL_COPY_H_
16
17#include <cstdint>
18#include <functional>
19#include <vector>
20
21#include "absl/container/flat_hash_set.h"
22#include "absl/types/span.h"
23#include "ortools/sat/cp_model.pb.h"
25#include "ortools/sat/sat_parameters.pb.h"
27
28namespace operations_research {
29namespace sat {
30
31// This helper class perform copy with simplification from a model and a
32// partial assignment to another model. The purpose is to minimize the size of
33// the copied model, as well as to reduce the pressure on the memory sub-system.
34//
35// It is currently used by the LNS part, but could be used with any other scheme
36// that generates partial assignments.
37class ModelCopy {
38 public:
39 explicit ModelCopy(PresolveContext* context);
40
41 // Copies all constraints from in_model to working model of the context.
42 //
43 // During the process, it will read variable domains from the context, and
44 // simplify constraints to minimize the size of the copied model.
45 // Thus it is important that the context->working_model already have the
46 // variables part copied.
47 //
48 // It returns false iff the model is proven infeasible.
49 //
50 // It does not clear the constraints part of the working model of the context.
51 //
52 // Note(user): If first_copy is true, we will reorder the scheduling
53 // constraint so that they only use reference to previously defined intervals.
54 // This allow to be more efficient later in a few preprocessing steps.
56 const CpModelProto& in_model, bool first_copy = false,
57 std::function<bool(int)> active_constraints = nullptr);
58
59 // Copy variables from the in_model to the working model.
60 // It reads the 'ignore_names' parameters from the context, and keeps or
61 // deletes names accordingly.
62 void ImportVariablesAndMaybeIgnoreNames(const CpModelProto& in_model);
63
64 // Setup new variables from a vector of domains.
65 // Inactive variables will be fixed to their lower bound.
66 void CreateVariablesFromDomains(absl::Span<const Domain> domains);
67
68 private:
69 // Overwrites the out_model to be unsat. Returns false.
70 // The arguments are used to log which constraint caused unsat.
71 bool CreateUnsatModel(int c, const ConstraintProto& ct);
72
73 // Returns false if the constraint is never enforced and can be skipped.
74 bool PrepareEnforcementCopy(const ConstraintProto& ct);
75 bool PrepareEnforcementCopyWithDup(const ConstraintProto& ct);
76 void FinishEnforcementCopy(ConstraintProto* ct);
77
78 // All these functions return false if the constraint is found infeasible.
79 bool CopyBoolOr(const ConstraintProto& ct);
80 bool CopyBoolOrWithDupSupport(const ConstraintProto& ct);
81 bool FinishBoolOrCopy();
82
83 bool CopyBoolAnd(const ConstraintProto& ct);
84 bool CopyBoolAndWithDupSupport(const ConstraintProto& ct);
85
86 bool CopyAtMostOne(const ConstraintProto& ct);
87 bool CopyExactlyOne(const ConstraintProto& ct);
88
89 bool CopyElement(const ConstraintProto& ct);
90 bool CopyIntProd(const ConstraintProto& ct, bool ignore_names);
91 bool CopyIntDiv(const ConstraintProto& ct, bool ignore_names);
92 bool CopyIntMod(const ConstraintProto& ct, bool ignore_names);
93 bool CopyLinear(const ConstraintProto& ct, bool canonicalize);
94 bool CopyLinearExpression(const LinearExpressionProto& expr,
95 LinearExpressionProto* dst,
96 absl::Span<const int> enforcement_literals = {});
97 bool CopyAutomaton(const ConstraintProto& ct);
98 bool CopyTable(const ConstraintProto& ct);
99 bool CopyAllDiff(const ConstraintProto& ct);
100 bool CopyLinMax(const ConstraintProto& ct);
101
102 // If we "copy" an interval for a first time, we make sure to create the
103 // linear constraint between the start, size and end. This allow to simplify
104 // the input proto and client side code.
105 bool CopyInterval(const ConstraintProto& ct, int c, bool ignore_names);
106 bool AddLinearConstraintForInterval(const ConstraintProto& ct);
107
108 // These function remove unperformed intervals. Note that they requires
109 // interval to appear before (validated) as they test unperformed by testing
110 // if interval_mapping_ is empty.
111 void CopyAndMapNoOverlap(const ConstraintProto& ct);
112 void CopyAndMapNoOverlap2D(const ConstraintProto& ct);
113 bool CopyAndMapCumulative(const ConstraintProto& ct);
114
115 PresolveContext* context_;
116
117 // Temp vectors.
118 std::vector<int> non_fixed_variables_;
119 std::vector<int64_t> non_fixed_coefficients_;
120 std::vector<int64_t> interval_mapping_;
121 int starting_constraint_index_ = 0;
122
123 std::vector<int> temp_enforcement_literals_;
124 absl::flat_hash_set<int> temp_enforcement_literals_set_;
125
126 std::vector<int> temp_literals_;
127 absl::flat_hash_set<int> temp_literals_set_;
128
129 ConstraintProto tmp_constraint_;
130};
131
132// Copy in_model to the model in the presolve context.
133// It performs on the fly simplification, and returns false if the
134// model is proved infeasible. If reads the parameters 'ignore_names' and keeps
135// or deletes variables and constraints names accordingly.
136//
137// This should only be called on the first copy of the user given model.
138// Note that this reorder all constraints that use intervals last. We loose the
139// user-defined order, but hopefully that should not matter too much.
140bool ImportModelWithBasicPresolveIntoContext(const CpModelProto& in_model,
141 PresolveContext* context);
142
143// Same as ImportModelWithBasicPresolveIntoContext() except that variable
144// domains are read from domains.
146 const CpModelProto& in_model, absl::Span<const Domain> domains,
147 std::function<bool(int)> active_constraints, PresolveContext* context);
148
149// Copies the non constraint, non variables part of the model.
151 const CpModelProto& in_model, PresolveContext* context);
152
153} // namespace sat
154} // namespace operations_research
155
156#endif // OR_TOOLS_SAT_CP_MODEL_COPY_H_
void ImportVariablesAndMaybeIgnoreNames(const CpModelProto &in_model)
void CreateVariablesFromDomains(absl::Span< const Domain > domains)
ModelCopy(PresolveContext *context)
bool ImportAndSimplifyConstraints(const CpModelProto &in_model, bool first_copy=false, std::function< bool(int)> active_constraints=nullptr)
bool ImportModelAndDomainsWithBasicPresolveIntoContext(const CpModelProto &in_model, absl::Span< const Domain > domains, std::function< bool(int)> active_constraints, PresolveContext *context)
bool ImportModelWithBasicPresolveIntoContext(const CpModelProto &in_model, PresolveContext *context)
void CopyEverythingExceptVariablesAndConstraintsFieldsIntoContext(const CpModelProto &in_model, PresolveContext *context)
Copies the non constraint, non variables part of the model.
In SWIG mode, we don't want anything besides these top-level includes.