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