OR-Tools  9.3
cp_model_utils.cc
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
15
16#include <cstdint>
17#include <cstdlib>
18#include <functional>
19#include <string>
20#include <vector>
21
22#include "absl/container/flat_hash_map.h"
25#include "ortools/sat/cp_model.pb.h"
27
28namespace operations_research {
29namespace sat {
30
31namespace {
32
33template <typename IntList>
34void AddIndices(const IntList& indices, std::vector<int>* output) {
35 output->insert(output->end(), indices.begin(), indices.end());
36}
37
38} // namespace
39
40void SetToNegatedLinearExpression(const LinearExpressionProto& input_expr,
41 LinearExpressionProto* output_negated_expr) {
42 output_negated_expr->Clear();
43 for (int i = 0; i < input_expr.vars_size(); ++i) {
44 output_negated_expr->add_vars(NegatedRef(input_expr.vars(i)));
45 output_negated_expr->add_coeffs(input_expr.coeffs(i));
46 }
47 output_negated_expr->set_offset(-input_expr.offset());
48}
49
51 IndexReferences output;
52 switch (ct.constraint_case()) {
53 case ConstraintProto::ConstraintCase::kBoolOr:
54 AddIndices(ct.bool_or().literals(), &output.literals);
55 break;
56 case ConstraintProto::ConstraintCase::kBoolAnd:
57 AddIndices(ct.bool_and().literals(), &output.literals);
58 break;
59 case ConstraintProto::ConstraintCase::kAtMostOne:
60 AddIndices(ct.at_most_one().literals(), &output.literals);
61 break;
62 case ConstraintProto::ConstraintCase::kExactlyOne:
63 AddIndices(ct.exactly_one().literals(), &output.literals);
64 break;
65 case ConstraintProto::ConstraintCase::kBoolXor:
66 AddIndices(ct.bool_xor().literals(), &output.literals);
67 break;
68 case ConstraintProto::ConstraintCase::kIntDiv:
69 AddIndices(ct.int_div().target().vars(), &output.variables);
70 for (const LinearExpressionProto& expr : ct.int_div().exprs()) {
71 AddIndices(expr.vars(), &output.variables);
72 }
73 break;
74 case ConstraintProto::ConstraintCase::kIntMod:
75 AddIndices(ct.int_mod().target().vars(), &output.variables);
76 for (const LinearExpressionProto& expr : ct.int_mod().exprs()) {
77 AddIndices(expr.vars(), &output.variables);
78 }
79 break;
80 case ConstraintProto::ConstraintCase::kLinMax: {
81 AddIndices(ct.lin_max().target().vars(), &output.variables);
82 for (const LinearExpressionProto& expr : ct.lin_max().exprs()) {
83 AddIndices(expr.vars(), &output.variables);
84 }
85 break;
86 }
87 case ConstraintProto::ConstraintCase::kIntProd:
88 AddIndices(ct.int_prod().target().vars(), &output.variables);
89 for (const LinearExpressionProto& expr : ct.int_prod().exprs()) {
90 AddIndices(expr.vars(), &output.variables);
91 }
92 break;
93 case ConstraintProto::ConstraintCase::kLinear:
94 AddIndices(ct.linear().vars(), &output.variables);
95 break;
96 case ConstraintProto::ConstraintCase::kAllDiff:
97 for (const LinearExpressionProto& expr : ct.all_diff().exprs()) {
98 AddIndices(expr.vars(), &output.variables);
99 }
100 break;
101 case ConstraintProto::ConstraintCase::kDummyConstraint:
102 AddIndices(ct.dummy_constraint().vars(), &output.variables);
103 break;
104 case ConstraintProto::ConstraintCase::kElement:
105 output.variables.push_back(ct.element().index());
106 output.variables.push_back(ct.element().target());
107 AddIndices(ct.element().vars(), &output.variables);
108 break;
109 case ConstraintProto::ConstraintCase::kCircuit:
110 AddIndices(ct.circuit().literals(), &output.literals);
111 break;
112 case ConstraintProto::ConstraintCase::kRoutes:
113 AddIndices(ct.routes().literals(), &output.literals);
114 break;
115 case ConstraintProto::ConstraintCase::kInverse:
116 AddIndices(ct.inverse().f_direct(), &output.variables);
117 AddIndices(ct.inverse().f_inverse(), &output.variables);
118 break;
119 case ConstraintProto::ConstraintCase::kReservoir:
120 for (const LinearExpressionProto& time : ct.reservoir().time_exprs()) {
121 AddIndices(time.vars(), &output.variables);
122 }
123 AddIndices(ct.reservoir().active_literals(), &output.literals);
124 break;
125 case ConstraintProto::ConstraintCase::kTable:
126 AddIndices(ct.table().vars(), &output.variables);
127 break;
128 case ConstraintProto::ConstraintCase::kAutomaton:
129 AddIndices(ct.automaton().vars(), &output.variables);
130 break;
131 case ConstraintProto::ConstraintCase::kInterval:
132 AddIndices(ct.interval().start().vars(), &output.variables);
133 AddIndices(ct.interval().size().vars(), &output.variables);
134 AddIndices(ct.interval().end().vars(), &output.variables);
135 break;
136 case ConstraintProto::ConstraintCase::kNoOverlap:
137 break;
138 case ConstraintProto::ConstraintCase::kNoOverlap2D:
139 break;
140 case ConstraintProto::ConstraintCase::kCumulative:
141 AddIndices(ct.cumulative().capacity().vars(), &output.variables);
142 for (const LinearExpressionProto& demand : ct.cumulative().demands()) {
143 AddIndices(demand.vars(), &output.variables);
144 }
145 break;
146 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
147 break;
148 }
149 return output;
150}
151
152#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
153 { \
154 int temp = ct->mutable_##ct_name()->field_name(); \
155 f(&temp); \
156 ct->mutable_##ct_name()->set_##field_name(temp); \
157 }
158
159#define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
160 { \
161 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
162 }
163
164void ApplyToAllLiteralIndices(const std::function<void(int*)>& f,
165 ConstraintProto* ct) {
166 for (int& r : *ct->mutable_enforcement_literal()) f(&r);
167 switch (ct->constraint_case()) {
168 case ConstraintProto::ConstraintCase::kBoolOr:
169 APPLY_TO_REPEATED_FIELD(bool_or, literals);
170 break;
171 case ConstraintProto::ConstraintCase::kBoolAnd:
172 APPLY_TO_REPEATED_FIELD(bool_and, literals);
173 break;
174 case ConstraintProto::ConstraintCase::kAtMostOne:
175 APPLY_TO_REPEATED_FIELD(at_most_one, literals);
176 break;
177 case ConstraintProto::ConstraintCase::kExactlyOne:
178 APPLY_TO_REPEATED_FIELD(exactly_one, literals);
179 break;
180 case ConstraintProto::ConstraintCase::kBoolXor:
181 APPLY_TO_REPEATED_FIELD(bool_xor, literals);
182 break;
183 case ConstraintProto::ConstraintCase::kIntDiv:
184 break;
185 case ConstraintProto::ConstraintCase::kIntMod:
186 break;
187 case ConstraintProto::ConstraintCase::kLinMax:
188 break;
189 case ConstraintProto::ConstraintCase::kIntProd:
190 break;
191 case ConstraintProto::ConstraintCase::kLinear:
192 break;
193 case ConstraintProto::ConstraintCase::kAllDiff:
194 break;
195 case ConstraintProto::ConstraintCase::kDummyConstraint:
196 break;
197 case ConstraintProto::ConstraintCase::kElement:
198 break;
199 case ConstraintProto::ConstraintCase::kCircuit:
200 APPLY_TO_REPEATED_FIELD(circuit, literals);
201 break;
202 case ConstraintProto::ConstraintCase::kRoutes:
203 APPLY_TO_REPEATED_FIELD(routes, literals);
204 break;
205 case ConstraintProto::ConstraintCase::kInverse:
206 break;
207 case ConstraintProto::ConstraintCase::kReservoir:
208 APPLY_TO_REPEATED_FIELD(reservoir, active_literals);
209 break;
210 case ConstraintProto::ConstraintCase::kTable:
211 break;
212 case ConstraintProto::ConstraintCase::kAutomaton:
213 break;
214 case ConstraintProto::ConstraintCase::kInterval:
215 break;
216 case ConstraintProto::ConstraintCase::kNoOverlap:
217 break;
218 case ConstraintProto::ConstraintCase::kNoOverlap2D:
219 break;
220 case ConstraintProto::ConstraintCase::kCumulative:
221 break;
222 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
223 break;
224 }
225}
226
227void ApplyToAllVariableIndices(const std::function<void(int*)>& f,
228 ConstraintProto* ct) {
229 switch (ct->constraint_case()) {
230 case ConstraintProto::ConstraintCase::kBoolOr:
231 break;
232 case ConstraintProto::ConstraintCase::kBoolAnd:
233 break;
234 case ConstraintProto::ConstraintCase::kAtMostOne:
235 break;
236 case ConstraintProto::ConstraintCase::kExactlyOne:
237 break;
238 case ConstraintProto::ConstraintCase::kBoolXor:
239 break;
240 case ConstraintProto::ConstraintCase::kIntDiv:
241 APPLY_TO_REPEATED_FIELD(int_div, target()->mutable_vars);
242 for (int i = 0; i < ct->int_div().exprs_size(); ++i) {
243 APPLY_TO_REPEATED_FIELD(int_div, exprs(i)->mutable_vars);
244 }
245 break;
246 case ConstraintProto::ConstraintCase::kIntMod:
247 APPLY_TO_REPEATED_FIELD(int_mod, target()->mutable_vars);
248 for (int i = 0; i < ct->int_mod().exprs_size(); ++i) {
249 APPLY_TO_REPEATED_FIELD(int_mod, exprs(i)->mutable_vars);
250 }
251 break;
252 case ConstraintProto::ConstraintCase::kLinMax:
253 APPLY_TO_REPEATED_FIELD(lin_max, target()->mutable_vars);
254 for (int i = 0; i < ct->lin_max().exprs_size(); ++i) {
255 APPLY_TO_REPEATED_FIELD(lin_max, exprs(i)->mutable_vars);
256 }
257 break;
258 case ConstraintProto::ConstraintCase::kIntProd:
259 APPLY_TO_REPEATED_FIELD(int_prod, target()->mutable_vars);
260 for (int i = 0; i < ct->int_prod().exprs_size(); ++i) {
261 APPLY_TO_REPEATED_FIELD(int_prod, exprs(i)->mutable_vars);
262 }
263 break;
264 case ConstraintProto::ConstraintCase::kLinear:
265 APPLY_TO_REPEATED_FIELD(linear, vars);
266 break;
267 case ConstraintProto::ConstraintCase::kAllDiff:
268 for (int i = 0; i < ct->all_diff().exprs_size(); ++i) {
269 APPLY_TO_REPEATED_FIELD(all_diff, exprs(i)->mutable_vars);
270 }
271 break;
272 case ConstraintProto::ConstraintCase::kDummyConstraint:
273 APPLY_TO_REPEATED_FIELD(dummy_constraint, vars);
274 break;
275 case ConstraintProto::ConstraintCase::kElement:
277 APPLY_TO_SINGULAR_FIELD(element, target);
278 APPLY_TO_REPEATED_FIELD(element, vars);
279 break;
280 case ConstraintProto::ConstraintCase::kCircuit:
281 break;
282 case ConstraintProto::ConstraintCase::kRoutes:
283 break;
284 case ConstraintProto::ConstraintCase::kInverse:
285 APPLY_TO_REPEATED_FIELD(inverse, f_direct);
286 APPLY_TO_REPEATED_FIELD(inverse, f_inverse);
287 break;
288 case ConstraintProto::ConstraintCase::kReservoir:
289 for (int i = 0; i < ct->reservoir().time_exprs_size(); ++i) {
290 APPLY_TO_REPEATED_FIELD(reservoir, time_exprs(i)->mutable_vars);
291 }
292 break;
293 case ConstraintProto::ConstraintCase::kTable:
294 APPLY_TO_REPEATED_FIELD(table, vars);
295 break;
296 case ConstraintProto::ConstraintCase::kAutomaton:
297 APPLY_TO_REPEATED_FIELD(automaton, vars);
298 break;
299 case ConstraintProto::ConstraintCase::kInterval:
300 APPLY_TO_REPEATED_FIELD(interval, start()->mutable_vars);
301 APPLY_TO_REPEATED_FIELD(interval, size()->mutable_vars);
302 APPLY_TO_REPEATED_FIELD(interval, end()->mutable_vars);
303 break;
304 case ConstraintProto::ConstraintCase::kNoOverlap:
305 break;
306 case ConstraintProto::ConstraintCase::kNoOverlap2D:
307 break;
308 case ConstraintProto::ConstraintCase::kCumulative:
309 APPLY_TO_REPEATED_FIELD(cumulative, capacity()->mutable_vars);
310 for (int i = 0; i < ct->cumulative().demands_size(); ++i) {
311 for (int& r :
312 *ct->mutable_cumulative()->mutable_demands(i)->mutable_vars()) {
313 f(&r);
314 }
315 }
316 break;
317 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
318 break;
319 }
320}
321
322void ApplyToAllIntervalIndices(const std::function<void(int*)>& f,
323 ConstraintProto* ct) {
324 switch (ct->constraint_case()) {
325 case ConstraintProto::ConstraintCase::kBoolOr:
326 break;
327 case ConstraintProto::ConstraintCase::kBoolAnd:
328 break;
329 case ConstraintProto::ConstraintCase::kAtMostOne:
330 break;
331 case ConstraintProto::ConstraintCase::kExactlyOne:
332 break;
333 case ConstraintProto::ConstraintCase::kBoolXor:
334 break;
335 case ConstraintProto::ConstraintCase::kIntDiv:
336 break;
337 case ConstraintProto::ConstraintCase::kIntMod:
338 break;
339 case ConstraintProto::ConstraintCase::kLinMax:
340 break;
341 case ConstraintProto::ConstraintCase::kIntProd:
342 break;
343 case ConstraintProto::ConstraintCase::kLinear:
344 break;
345 case ConstraintProto::ConstraintCase::kAllDiff:
346 break;
347 case ConstraintProto::ConstraintCase::kDummyConstraint:
348 break;
349 case ConstraintProto::ConstraintCase::kElement:
350 break;
351 case ConstraintProto::ConstraintCase::kCircuit:
352 break;
353 case ConstraintProto::ConstraintCase::kRoutes:
354 break;
355 case ConstraintProto::ConstraintCase::kInverse:
356 break;
357 case ConstraintProto::ConstraintCase::kReservoir:
358 break;
359 case ConstraintProto::ConstraintCase::kTable:
360 break;
361 case ConstraintProto::ConstraintCase::kAutomaton:
362 break;
363 case ConstraintProto::ConstraintCase::kInterval:
364 break;
365 case ConstraintProto::ConstraintCase::kNoOverlap:
366 APPLY_TO_REPEATED_FIELD(no_overlap, intervals);
367 break;
368 case ConstraintProto::ConstraintCase::kNoOverlap2D:
369 APPLY_TO_REPEATED_FIELD(no_overlap_2d, x_intervals);
370 APPLY_TO_REPEATED_FIELD(no_overlap_2d, y_intervals);
371 break;
372 case ConstraintProto::ConstraintCase::kCumulative:
373 APPLY_TO_REPEATED_FIELD(cumulative, intervals);
374 break;
375 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
376 break;
377 }
378}
379
380#undef APPLY_TO_SINGULAR_FIELD
381#undef APPLY_TO_REPEATED_FIELD
382
384 ConstraintProto::ConstraintCase constraint_case) {
385 switch (constraint_case) {
386 case ConstraintProto::ConstraintCase::kBoolOr:
387 return "kBoolOr";
388 case ConstraintProto::ConstraintCase::kBoolAnd:
389 return "kBoolAnd";
390 case ConstraintProto::ConstraintCase::kAtMostOne:
391 return "kAtMostOne";
392 case ConstraintProto::ConstraintCase::kExactlyOne:
393 return "kExactlyOne";
394 case ConstraintProto::ConstraintCase::kBoolXor:
395 return "kBoolXor";
396 case ConstraintProto::ConstraintCase::kIntDiv:
397 return "kIntDiv";
398 case ConstraintProto::ConstraintCase::kIntMod:
399 return "kIntMod";
400 case ConstraintProto::ConstraintCase::kLinMax:
401 return "kLinMax";
402 case ConstraintProto::ConstraintCase::kIntProd:
403 return "kIntProd";
404 case ConstraintProto::ConstraintCase::kLinear:
405 return "kLinear";
406 case ConstraintProto::ConstraintCase::kAllDiff:
407 return "kAllDiff";
408 case ConstraintProto::ConstraintCase::kDummyConstraint:
409 return "kDummyConstraint";
410 case ConstraintProto::ConstraintCase::kElement:
411 return "kElement";
412 case ConstraintProto::ConstraintCase::kCircuit:
413 return "kCircuit";
414 case ConstraintProto::ConstraintCase::kRoutes:
415 return "kRoutes";
416 case ConstraintProto::ConstraintCase::kInverse:
417 return "kInverse";
418 case ConstraintProto::ConstraintCase::kReservoir:
419 return "kReservoir";
420 case ConstraintProto::ConstraintCase::kTable:
421 return "kTable";
422 case ConstraintProto::ConstraintCase::kAutomaton:
423 return "kAutomaton";
424 case ConstraintProto::ConstraintCase::kInterval:
425 return "kInterval";
426 case ConstraintProto::ConstraintCase::kNoOverlap:
427 return "kNoOverlap";
428 case ConstraintProto::ConstraintCase::kNoOverlap2D:
429 return "kNoOverlap2D";
430 case ConstraintProto::ConstraintCase::kCumulative:
431 return "kCumulative";
432 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
433 return "kEmpty";
434 }
435}
436
437std::vector<int> UsedVariables(const ConstraintProto& ct) {
439 for (int& ref : references.variables) {
440 ref = PositiveRef(ref);
441 }
442 for (const int lit : references.literals) {
443 references.variables.push_back(PositiveRef(lit));
444 }
445 for (const int lit : ct.enforcement_literal()) {
446 references.variables.push_back(PositiveRef(lit));
447 }
449 return references.variables;
450}
451
452std::vector<int> UsedIntervals(const ConstraintProto& ct) {
453 std::vector<int> used_intervals;
454 switch (ct.constraint_case()) {
455 case ConstraintProto::ConstraintCase::kBoolOr:
456 break;
457 case ConstraintProto::ConstraintCase::kBoolAnd:
458 break;
459 case ConstraintProto::ConstraintCase::kAtMostOne:
460 break;
461 case ConstraintProto::ConstraintCase::kExactlyOne:
462 break;
463 case ConstraintProto::ConstraintCase::kBoolXor:
464 break;
465 case ConstraintProto::ConstraintCase::kIntDiv:
466 break;
467 case ConstraintProto::ConstraintCase::kIntMod:
468 break;
469 case ConstraintProto::ConstraintCase::kLinMax:
470 break;
471 case ConstraintProto::ConstraintCase::kIntProd:
472 break;
473 case ConstraintProto::ConstraintCase::kLinear:
474 break;
475 case ConstraintProto::ConstraintCase::kAllDiff:
476 break;
477 case ConstraintProto::ConstraintCase::kDummyConstraint:
478 break;
479 case ConstraintProto::ConstraintCase::kElement:
480 break;
481 case ConstraintProto::ConstraintCase::kCircuit:
482 break;
483 case ConstraintProto::ConstraintCase::kRoutes:
484 break;
485 case ConstraintProto::ConstraintCase::kInverse:
486 break;
487 case ConstraintProto::ConstraintCase::kReservoir:
488 break;
489 case ConstraintProto::ConstraintCase::kTable:
490 break;
491 case ConstraintProto::ConstraintCase::kAutomaton:
492 break;
493 case ConstraintProto::ConstraintCase::kInterval:
494 break;
495 case ConstraintProto::ConstraintCase::kNoOverlap:
496 AddIndices(ct.no_overlap().intervals(), &used_intervals);
497 break;
498 case ConstraintProto::ConstraintCase::kNoOverlap2D:
499 AddIndices(ct.no_overlap_2d().x_intervals(), &used_intervals);
500 AddIndices(ct.no_overlap_2d().y_intervals(), &used_intervals);
501 break;
502 case ConstraintProto::ConstraintCase::kCumulative:
503 AddIndices(ct.cumulative().intervals(), &used_intervals);
504 break;
505 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
506 break;
507 }
508 gtl::STLSortAndRemoveDuplicates(&used_intervals);
509 return used_intervals;
510}
511
512int64_t ComputeInnerObjective(const CpObjectiveProto& objective,
513 const CpSolverResponse& response) {
514 int64_t objective_value = 0;
515 for (int i = 0; i < objective.vars_size(); ++i) {
516 int64_t coeff = objective.coeffs(i);
517 const int ref = objective.vars(i);
518 const int var = PositiveRef(ref);
519 if (!RefIsPositive(ref)) coeff = -coeff;
520 objective_value += coeff * response.solution()[var];
521 }
522 return objective_value;
523}
524
525bool ExpressionContainsSingleRef(const LinearExpressionProto& expr) {
526 return expr.offset() == 0 && expr.vars_size() == 1 &&
527 std::abs(expr.coeffs(0)) == 1;
528}
529
530bool ExpressionIsAffine(const LinearExpressionProto& expr) {
531 return expr.vars_size() <= 1;
532}
533
534// Returns the reference the expression can be reduced to. It will DCHECK that
535// ExpressionContainsSingleRef(expr) is true.
536int GetSingleRefFromExpression(const LinearExpressionProto& expr) {
538 return expr.coeffs(0) == 1 ? expr.vars(0) : NegatedRef(expr.vars(0));
539}
540
541void AddLinearExpressionToLinearConstraint(const LinearExpressionProto& expr,
542 int64_t coefficient,
543 LinearConstraintProto* linear) {
544 for (int i = 0; i < expr.vars_size(); ++i) {
545 linear->add_vars(expr.vars(i));
546 linear->add_coeffs(expr.coeffs(i) * coefficient);
547 }
548 DCHECK(!linear->domain().empty());
549 const int64_t shift = coefficient * expr.offset();
550 if (shift != 0) {
552 linear);
553 }
554}
555
556bool LinearExpressionProtosAreEqual(const LinearExpressionProto& a,
557 const LinearExpressionProto& b,
558 int64_t b_scaling) {
559 if (a.vars_size() != b.vars_size()) return false;
560 if (a.offset() != b.offset() * b_scaling) return false;
561 absl::flat_hash_map<int, int64_t> coeffs;
562 for (int i = 0; i < a.vars_size(); ++i) {
563 coeffs[a.vars(i)] += a.coeffs(i);
564 coeffs[b.vars(i)] += -b.coeffs(i) * b_scaling;
565 }
566
567 for (const auto [var, coeff] : coeffs) {
568 if (coeff != 0) return false;
569 }
570 return true;
571}
572
573} // namespace sat
574} // namespace operations_research
#define DCHECK(condition)
Definition: base/logging.h:890
We call domain any subset of Int64 = [kint64min, kint64max].
Domain AdditionWith(const Domain &domain) const
Returns {x ∈ Int64, ∃ a ∈ D, ∃ b ∈ domain, x = a + b}.
int64_t b
int64_t a
SharedResponseManager * response
#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name)
#define APPLY_TO_REPEATED_FIELD(ct_name, field_name)
const Constraint * ct
IntVar * var
Definition: expr_array.cc:1874
int index
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
Definition: stl_util.h:58
int64_t ComputeInnerObjective(const CpObjectiveProto &objective, const CpSolverResponse &response)
std::vector< int > UsedVariables(const ConstraintProto &ct)
bool RefIsPositive(int ref)
std::vector< int > UsedIntervals(const ConstraintProto &ct)
void SetToNegatedLinearExpression(const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr)
void ApplyToAllLiteralIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
bool LinearExpressionProtosAreEqual(const LinearExpressionProto &a, const LinearExpressionProto &b, int64_t b_scaling)
void ApplyToAllIntervalIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
void FillDomainInProto(const Domain &domain, ProtoWithDomain *proto)
bool ExpressionIsAffine(const LinearExpressionProto &expr)
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
void ApplyToAllVariableIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
IndexReferences GetReferencesUsedByConstraint(const ConstraintProto &ct)
void AddLinearExpressionToLinearConstraint(const LinearExpressionProto &expr, int64_t coefficient, LinearConstraintProto *linear)
std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case)
int GetSingleRefFromExpression(const LinearExpressionProto &expr)
bool ExpressionContainsSingleRef(const LinearExpressionProto &expr)
Collection of objects used to extend the Constraint Solver library.
int64_t demand
Definition: resource.cc:125
int64_t time
Definition: resource.cc:1693
IntervalVar * interval
Definition: resource.cc:100
int64_t coefficient
int64_t capacity
std::optional< int64_t > end
int64_t start
double objective_value
const double coeff