23template <
typename IntList>
24void AddIndices(
const IntList& indices, std::vector<int>* output) {
25 output->insert(output->end(), indices.begin(), indices.end());
31 LinearExpressionProto* output_negated_expr) {
32 output_negated_expr->Clear();
33 for (
int i = 0; i < input_expr.vars_size(); ++i) {
34 output_negated_expr->add_vars(
NegatedRef(input_expr.vars(i)));
35 output_negated_expr->add_coeffs(input_expr.coeffs(i));
37 output_negated_expr->set_offset(-input_expr.offset());
42 switch (
ct.constraint_case()) {
43 case ConstraintProto::ConstraintCase::kBoolOr:
44 AddIndices(
ct.bool_or().literals(), &output.
literals);
46 case ConstraintProto::ConstraintCase::kBoolAnd:
47 AddIndices(
ct.bool_and().literals(), &output.
literals);
49 case ConstraintProto::ConstraintCase::kAtMostOne:
50 AddIndices(
ct.at_most_one().literals(), &output.
literals);
52 case ConstraintProto::ConstraintCase::kExactlyOne:
53 AddIndices(
ct.exactly_one().literals(), &output.
literals);
55 case ConstraintProto::ConstraintCase::kBoolXor:
56 AddIndices(
ct.bool_xor().literals(), &output.
literals);
58 case ConstraintProto::ConstraintCase::kIntDiv:
62 case ConstraintProto::ConstraintCase::kIntMod:
66 case ConstraintProto::ConstraintCase::kIntMax:
70 case ConstraintProto::ConstraintCase::kLinMax: {
71 AddIndices(
ct.lin_max().target().vars(), &output.
variables);
72 for (
int i = 0; i <
ct.lin_max().exprs_size(); ++i) {
73 AddIndices(
ct.lin_max().exprs(i).vars(), &output.
variables);
77 case ConstraintProto::ConstraintCase::kIntMin:
81 case ConstraintProto::ConstraintCase::kLinMin: {
82 AddIndices(
ct.lin_min().target().vars(), &output.
variables);
83 for (
int i = 0; i <
ct.lin_min().exprs_size(); ++i) {
84 AddIndices(
ct.lin_min().exprs(i).vars(), &output.
variables);
88 case ConstraintProto::ConstraintCase::kIntProd:
90 AddIndices(
ct.int_prod().vars(), &output.
variables);
92 case ConstraintProto::ConstraintCase::kLinear:
95 case ConstraintProto::ConstraintCase::kAllDiff:
96 AddIndices(
ct.all_diff().vars(), &output.
variables);
98 case ConstraintProto::ConstraintCase::kElement:
101 AddIndices(
ct.element().vars(), &output.
variables);
103 case ConstraintProto::ConstraintCase::kCircuit:
104 AddIndices(
ct.circuit().literals(), &output.
literals);
106 case ConstraintProto::ConstraintCase::kRoutes:
107 AddIndices(
ct.routes().literals(), &output.
literals);
109 case ConstraintProto::ConstraintCase::kInverse:
110 AddIndices(
ct.inverse().f_direct(), &output.
variables);
111 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
113 case ConstraintProto::ConstraintCase::kReservoir:
114 AddIndices(
ct.reservoir().times(), &output.
variables);
115 AddIndices(
ct.reservoir().actives(), &output.
literals);
117 case ConstraintProto::ConstraintCase::kTable:
120 case ConstraintProto::ConstraintCase::kAutomaton:
121 AddIndices(
ct.automaton().vars(), &output.
variables);
123 case ConstraintProto::ConstraintCase::kInterval:
124 if (
ct.interval().has_start_view()) {
125 AddIndices(
ct.interval().start_view().vars(), &output.
variables);
129 if (
ct.interval().has_size_view()) {
130 AddIndices(
ct.interval().size_view().vars(), &output.
variables);
134 if (
ct.interval().has_end_view()) {
135 AddIndices(
ct.interval().end_view().vars(), &output.
variables);
140 case ConstraintProto::ConstraintCase::kNoOverlap:
142 case ConstraintProto::ConstraintCase::kNoOverlap2D:
144 case ConstraintProto::ConstraintCase::kCumulative:
145 output.
variables.push_back(
ct.cumulative().capacity());
146 AddIndices(
ct.cumulative().demands(), &output.
variables);
148 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
154#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
156 int temp = ct->mutable_##ct_name()->field_name(); \
158 ct->mutable_##ct_name()->set_##field_name(temp); \
161#define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
163 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
167 ConstraintProto*
ct) {
168 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
169 switch (
ct->constraint_case()) {
170 case ConstraintProto::ConstraintCase::kBoolOr:
173 case ConstraintProto::ConstraintCase::kBoolAnd:
176 case ConstraintProto::ConstraintCase::kAtMostOne:
179 case ConstraintProto::ConstraintCase::kExactlyOne:
182 case ConstraintProto::ConstraintCase::kBoolXor:
185 case ConstraintProto::ConstraintCase::kIntDiv:
187 case ConstraintProto::ConstraintCase::kIntMod:
189 case ConstraintProto::ConstraintCase::kIntMax:
191 case ConstraintProto::ConstraintCase::kLinMax:
193 case ConstraintProto::ConstraintCase::kIntMin:
195 case ConstraintProto::ConstraintCase::kLinMin:
197 case ConstraintProto::ConstraintCase::kIntProd:
199 case ConstraintProto::ConstraintCase::kLinear:
201 case ConstraintProto::ConstraintCase::kAllDiff:
203 case ConstraintProto::ConstraintCase::kElement:
205 case ConstraintProto::ConstraintCase::kCircuit:
208 case ConstraintProto::ConstraintCase::kRoutes:
211 case ConstraintProto::ConstraintCase::kInverse:
213 case ConstraintProto::ConstraintCase::kReservoir:
216 case ConstraintProto::ConstraintCase::kTable:
218 case ConstraintProto::ConstraintCase::kAutomaton:
220 case ConstraintProto::ConstraintCase::kInterval:
222 case ConstraintProto::ConstraintCase::kNoOverlap:
224 case ConstraintProto::ConstraintCase::kNoOverlap2D:
226 case ConstraintProto::ConstraintCase::kCumulative:
228 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
234 ConstraintProto*
ct) {
235 switch (
ct->constraint_case()) {
236 case ConstraintProto::ConstraintCase::kBoolOr:
238 case ConstraintProto::ConstraintCase::kBoolAnd:
240 case ConstraintProto::ConstraintCase::kAtMostOne:
242 case ConstraintProto::ConstraintCase::kExactlyOne:
244 case ConstraintProto::ConstraintCase::kBoolXor:
246 case ConstraintProto::ConstraintCase::kIntDiv:
250 case ConstraintProto::ConstraintCase::kIntMod:
254 case ConstraintProto::ConstraintCase::kIntMax:
258 case ConstraintProto::ConstraintCase::kLinMax:
260 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
264 case ConstraintProto::ConstraintCase::kIntMin:
268 case ConstraintProto::ConstraintCase::kLinMin:
270 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
274 case ConstraintProto::ConstraintCase::kIntProd:
278 case ConstraintProto::ConstraintCase::kLinear:
281 case ConstraintProto::ConstraintCase::kAllDiff:
284 case ConstraintProto::ConstraintCase::kElement:
289 case ConstraintProto::ConstraintCase::kCircuit:
291 case ConstraintProto::ConstraintCase::kRoutes:
293 case ConstraintProto::ConstraintCase::kInverse:
297 case ConstraintProto::ConstraintCase::kReservoir:
300 case ConstraintProto::ConstraintCase::kTable:
303 case ConstraintProto::ConstraintCase::kAutomaton:
306 case ConstraintProto::ConstraintCase::kInterval:
307 if (
ct->interval().has_start_view()) {
312 if (
ct->interval().has_size_view()) {
317 if (
ct->interval().has_end_view()) {
323 case ConstraintProto::ConstraintCase::kNoOverlap:
325 case ConstraintProto::ConstraintCase::kNoOverlap2D:
327 case ConstraintProto::ConstraintCase::kCumulative:
331 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
337 ConstraintProto*
ct) {
338 switch (
ct->constraint_case()) {
339 case ConstraintProto::ConstraintCase::kBoolOr:
341 case ConstraintProto::ConstraintCase::kBoolAnd:
343 case ConstraintProto::ConstraintCase::kAtMostOne:
345 case ConstraintProto::ConstraintCase::kExactlyOne:
347 case ConstraintProto::ConstraintCase::kBoolXor:
349 case ConstraintProto::ConstraintCase::kIntDiv:
351 case ConstraintProto::ConstraintCase::kIntMod:
353 case ConstraintProto::ConstraintCase::kIntMax:
355 case ConstraintProto::ConstraintCase::kLinMax:
357 case ConstraintProto::ConstraintCase::kIntMin:
359 case ConstraintProto::ConstraintCase::kLinMin:
361 case ConstraintProto::ConstraintCase::kIntProd:
363 case ConstraintProto::ConstraintCase::kLinear:
365 case ConstraintProto::ConstraintCase::kAllDiff:
367 case ConstraintProto::ConstraintCase::kElement:
369 case ConstraintProto::ConstraintCase::kCircuit:
371 case ConstraintProto::ConstraintCase::kRoutes:
373 case ConstraintProto::ConstraintCase::kInverse:
375 case ConstraintProto::ConstraintCase::kReservoir:
377 case ConstraintProto::ConstraintCase::kTable:
379 case ConstraintProto::ConstraintCase::kAutomaton:
381 case ConstraintProto::ConstraintCase::kInterval:
383 case ConstraintProto::ConstraintCase::kNoOverlap:
386 case ConstraintProto::ConstraintCase::kNoOverlap2D:
390 case ConstraintProto::ConstraintCase::kCumulative:
393 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
398#undef APPLY_TO_SINGULAR_FIELD
399#undef APPLY_TO_REPEATED_FIELD
402 ConstraintProto::ConstraintCase constraint_case) {
403 switch (constraint_case) {
404 case ConstraintProto::ConstraintCase::kBoolOr:
406 case ConstraintProto::ConstraintCase::kBoolAnd:
408 case ConstraintProto::ConstraintCase::kAtMostOne:
410 case ConstraintProto::ConstraintCase::kExactlyOne:
411 return "kExactlyOne";
412 case ConstraintProto::ConstraintCase::kBoolXor:
414 case ConstraintProto::ConstraintCase::kIntDiv:
416 case ConstraintProto::ConstraintCase::kIntMod:
418 case ConstraintProto::ConstraintCase::kIntMax:
420 case ConstraintProto::ConstraintCase::kLinMax:
422 case ConstraintProto::ConstraintCase::kIntMin:
424 case ConstraintProto::ConstraintCase::kLinMin:
426 case ConstraintProto::ConstraintCase::kIntProd:
428 case ConstraintProto::ConstraintCase::kLinear:
430 case ConstraintProto::ConstraintCase::kAllDiff:
432 case ConstraintProto::ConstraintCase::kElement:
434 case ConstraintProto::ConstraintCase::kCircuit:
436 case ConstraintProto::ConstraintCase::kRoutes:
438 case ConstraintProto::ConstraintCase::kInverse:
440 case ConstraintProto::ConstraintCase::kReservoir:
442 case ConstraintProto::ConstraintCase::kTable:
444 case ConstraintProto::ConstraintCase::kAutomaton:
446 case ConstraintProto::ConstraintCase::kInterval:
448 case ConstraintProto::ConstraintCase::kNoOverlap:
450 case ConstraintProto::ConstraintCase::kNoOverlap2D:
451 return "kNoOverlap2D";
452 case ConstraintProto::ConstraintCase::kCumulative:
453 return "kCumulative";
454 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
464 for (
const int lit : references.
literals) {
467 for (
const int lit :
ct.enforcement_literal()) {
475 std::vector<int> used_intervals;
476 switch (
ct.constraint_case()) {
477 case ConstraintProto::ConstraintCase::kBoolOr:
479 case ConstraintProto::ConstraintCase::kBoolAnd:
481 case ConstraintProto::ConstraintCase::kAtMostOne:
483 case ConstraintProto::ConstraintCase::kExactlyOne:
485 case ConstraintProto::ConstraintCase::kBoolXor:
487 case ConstraintProto::ConstraintCase::kIntDiv:
489 case ConstraintProto::ConstraintCase::kIntMod:
491 case ConstraintProto::ConstraintCase::kIntMax:
493 case ConstraintProto::ConstraintCase::kLinMax:
495 case ConstraintProto::ConstraintCase::kIntMin:
497 case ConstraintProto::ConstraintCase::kLinMin:
499 case ConstraintProto::ConstraintCase::kIntProd:
501 case ConstraintProto::ConstraintCase::kLinear:
503 case ConstraintProto::ConstraintCase::kAllDiff:
505 case ConstraintProto::ConstraintCase::kElement:
507 case ConstraintProto::ConstraintCase::kCircuit:
509 case ConstraintProto::ConstraintCase::kRoutes:
511 case ConstraintProto::ConstraintCase::kInverse:
513 case ConstraintProto::ConstraintCase::kReservoir:
515 case ConstraintProto::ConstraintCase::kTable:
517 case ConstraintProto::ConstraintCase::kAutomaton:
519 case ConstraintProto::ConstraintCase::kInterval:
521 case ConstraintProto::ConstraintCase::kNoOverlap:
522 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
524 case ConstraintProto::ConstraintCase::kNoOverlap2D:
525 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
526 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
528 case ConstraintProto::ConstraintCase::kCumulative:
529 AddIndices(
ct.cumulative().intervals(), &used_intervals);
531 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
535 return used_intervals;
540 int64 objective_value = 0;
541 auto& repeated_field_values =
response.solution().empty()
544 for (
int i = 0; i < objective.vars_size(); ++i) {
545 int64 coeff = objective.coeffs(i);
546 const int ref = objective.vars(i);
549 objective_value += coeff * repeated_field_values[
var];
551 return objective_value;
SharedResponseManager * response
#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name)
#define APPLY_TO_REPEATED_FIELD(ct_name, field_name)
void STLSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
std::vector< int > UsedVariables(const ConstraintProto &ct)
std::vector< int > UsedIntervals(const ConstraintProto &ct)
void SetToNegatedLinearExpression(const LinearExpressionProto &input_expr, LinearExpressionProto *output_negated_expr)
int64 ComputeInnerObjective(const CpObjectiveProto &objective, const CpSolverResponse &response)
void ApplyToAllLiteralIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
void ApplyToAllIntervalIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
void ApplyToAllVariableIndices(const std::function< void(int *)> &f, ConstraintProto *ct)
IndexReferences GetReferencesUsedByConstraint(const ConstraintProto &ct)
std::string ConstraintCaseName(ConstraintProto::ConstraintCase constraint_case)
bool RefIsPositive(int ref)
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
std::vector< int > variables
std::vector< int > literals