OR-Tools  9.3
cp_constraints.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_SAT_CP_CONSTRAINTS_H_
15#define OR_TOOLS_SAT_CP_CONSTRAINTS_H_
16
17#include <cstdint>
18#include <functional>
19#include <memory>
20#include <vector>
21
22#include "absl/types/span.h"
25#include "ortools/base/macros.h"
26#include "ortools/sat/integer.h"
27#include "ortools/sat/model.h"
29#include "ortools/util/rev.h"
31
32namespace operations_research {
33namespace sat {
34
35// Propagate the fact that a XOR of literals is equal to the given value.
36// The complexity is in O(n).
37//
38// TODO(user): By using a two watcher mechanism, we can propagate this a lot
39// faster.
41 public:
42 BooleanXorPropagator(const std::vector<Literal>& literals, bool value,
43 Trail* trail, IntegerTrail* integer_trail)
44 : literals_(literals),
45 value_(value),
46 trail_(trail),
47 integer_trail_(integer_trail) {}
48
49 bool Propagate() final;
51
52 private:
53 const std::vector<Literal> literals_;
54 const bool value_;
55 std::vector<Literal> literal_reason_;
56 Trail* trail_;
57 IntegerTrail* integer_trail_;
58
59 DISALLOW_COPY_AND_ASSIGN(BooleanXorPropagator);
60};
61
62// If we have:
63// - selectors[i] => (target_var >= vars[i] + offset[i])
64// - and we known that at least one selectors[i] must be true
65// then we can propagate the fact that if no selectors is chosen yet, the lower
66// bound of target_var is greater than the min of the still possible
67// alternatives.
68//
69// This constraint take care of this case when no selectors[i] is chosen yet.
70//
71// This constraint support duplicate selectors.
73 public:
75 IntegerVariable target_var, const absl::Span<const IntegerVariable> vars,
76 const absl::Span<const IntegerValue> offsets,
77 const absl::Span<const Literal> selectors,
78 const absl::Span<const Literal> enforcements, Model* model);
79
80 bool Propagate() final;
82
83 private:
84 const IntegerVariable target_var_;
85 const std::vector<IntegerVariable> vars_;
86 const std::vector<IntegerValue> offsets_;
87 const std::vector<Literal> selectors_;
88 const std::vector<Literal> enforcements_;
89
90 Trail* trail_;
91 IntegerTrail* integer_trail_;
92
93 std::vector<Literal> literal_reason_;
94 std::vector<IntegerLiteral> integer_reason_;
95
96 DISALLOW_COPY_AND_ASSIGN(GreaterThanAtLeastOneOfPropagator);
97};
98
99// ============================================================================
100// Model based functions.
101// ============================================================================
102
103inline std::vector<IntegerValue> ToIntegerValueVector(
104 const std::vector<int64_t>& input) {
105 std::vector<IntegerValue> result(input.size());
106 for (int i = 0; i < input.size(); ++i) {
107 result[i] = IntegerValue(input[i]);
108 }
109 return result;
110}
111
112// Enforces the XOR of a set of literals to be equal to the given value.
113inline std::function<void(Model*)> LiteralXorIs(
114 const std::vector<Literal>& literals, bool value) {
115 return [=](Model* model) {
116 Trail* trail = model->GetOrCreate<Trail>();
117 IntegerTrail* integer_trail = model->GetOrCreate<IntegerTrail>();
118 BooleanXorPropagator* constraint =
119 new BooleanXorPropagator(literals, value, trail, integer_trail);
120 constraint->RegisterWith(model->GetOrCreate<GenericLiteralWatcher>());
121 model->TakeOwnership(constraint);
122 };
123}
124
125inline std::function<void(Model*)> GreaterThanAtLeastOneOf(
126 IntegerVariable target_var, const absl::Span<const IntegerVariable> vars,
127 const absl::Span<const IntegerValue> offsets,
128 const absl::Span<const Literal> selectors) {
129 return [=](Model* model) {
131 new GreaterThanAtLeastOneOfPropagator(target_var, vars, offsets,
132 selectors, {}, model);
133 constraint->RegisterWith(model->GetOrCreate<GenericLiteralWatcher>());
134 model->TakeOwnership(constraint);
135 };
136}
137
138inline std::function<void(Model*)> GreaterThanAtLeastOneOf(
139 IntegerVariable target_var, const absl::Span<const IntegerVariable> vars,
140 const absl::Span<const IntegerValue> offsets,
141 const absl::Span<const Literal> selectors,
142 const absl::Span<const Literal> enforcements) {
143 return [=](Model* model) {
145 new GreaterThanAtLeastOneOfPropagator(target_var, vars, offsets,
146 selectors, enforcements, model);
147 constraint->RegisterWith(model->GetOrCreate<GenericLiteralWatcher>());
148 model->TakeOwnership(constraint);
149 };
150}
151
152// The target variable is equal to exactly one of the candidate variable. The
153// equality is controlled by the given "selector" literals.
154//
155// Note(user): This only propagate from the min/max of still possible candidates
156// to the min/max of the target variable. The full constraint also requires
157// to deal with the case when one of the literal is true.
158//
159// Note(user): If there is just one or two candidates, this doesn't add
160// anything.
161inline std::function<void(Model*)> PartialIsOneOfVar(
162 IntegerVariable target_var, const std::vector<IntegerVariable>& vars,
163 const std::vector<Literal>& selectors) {
164 CHECK_EQ(vars.size(), selectors.size());
165 return [=](Model* model) {
166 const std::vector<IntegerValue> offsets(vars.size(), IntegerValue(0));
167 if (vars.size() > 2) {
168 // Propagate the min.
169 model->Add(GreaterThanAtLeastOneOf(target_var, vars, offsets, selectors));
170 }
171 if (vars.size() > 2) {
172 // Propagate the max.
174 NegationOf(vars), offsets, selectors));
175 }
176 };
177}
178
179} // namespace sat
180} // namespace operations_research
181
182#endif // OR_TOOLS_SAT_CP_CONSTRAINTS_H_
const std::vector< IntVar * > vars_
Definition: alldiff_cst.cc:44
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:703
void RegisterWith(GenericLiteralWatcher *watcher)
BooleanXorPropagator(const std::vector< Literal > &literals, bool value, Trail *trail, IntegerTrail *integer_trail)
Class that owns everything related to a particular optimization model.
Definition: sat/model.h:42
int64_t value
GRBmodel * model
std::function< void(Model *)> LiteralXorIs(const std::vector< Literal > &literals, bool value)
std::vector< IntegerValue > ToIntegerValueVector(const std::vector< int64_t > &input)
std::function< void(Model *)> PartialIsOneOfVar(IntegerVariable target_var, const std::vector< IntegerVariable > &vars, const std::vector< Literal > &selectors)
std::function< void(Model *)> GreaterThanAtLeastOneOf(IntegerVariable target_var, const absl::Span< const IntegerVariable > vars, const absl::Span< const IntegerValue > offsets, const absl::Span< const Literal > selectors)
std::vector< IntegerVariable > NegationOf(const std::vector< IntegerVariable > &vars)
Definition: integer.cc:47
Collection of objects used to extend the Constraint Solver library.
STL namespace.
static int input(yyscan_t yyscanner)
IntervalVar *const target_var_