23 template <
typename IntList>
24 void 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::kBoolXor:
53 AddIndices(
ct.bool_xor().literals(), &output.
literals);
55 case ConstraintProto::ConstraintCase::kIntDiv:
59 case ConstraintProto::ConstraintCase::kIntMod:
63 case ConstraintProto::ConstraintCase::kIntMax:
67 case ConstraintProto::ConstraintCase::kLinMax: {
68 AddIndices(
ct.lin_max().target().vars(), &output.
variables);
69 for (
int i = 0; i <
ct.lin_max().exprs_size(); ++i) {
70 AddIndices(
ct.lin_max().exprs(i).vars(), &output.
variables);
74 case ConstraintProto::ConstraintCase::kIntMin:
78 case ConstraintProto::ConstraintCase::kLinMin: {
79 AddIndices(
ct.lin_min().target().vars(), &output.
variables);
80 for (
int i = 0; i <
ct.lin_min().exprs_size(); ++i) {
81 AddIndices(
ct.lin_min().exprs(i).vars(), &output.
variables);
85 case ConstraintProto::ConstraintCase::kIntProd:
87 AddIndices(
ct.int_prod().vars(), &output.
variables);
89 case ConstraintProto::ConstraintCase::kLinear:
92 case ConstraintProto::ConstraintCase::kAllDiff:
93 AddIndices(
ct.all_diff().vars(), &output.
variables);
95 case ConstraintProto::ConstraintCase::kElement:
100 case ConstraintProto::ConstraintCase::kCircuit:
101 AddIndices(
ct.circuit().literals(), &output.
literals);
103 case ConstraintProto::ConstraintCase::kRoutes:
104 AddIndices(
ct.routes().literals(), &output.
literals);
106 case ConstraintProto::ConstraintCase::kInverse:
107 AddIndices(
ct.inverse().f_direct(), &output.
variables);
108 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
110 case ConstraintProto::ConstraintCase::kReservoir:
111 AddIndices(
ct.reservoir().times(), &output.
variables);
112 AddIndices(
ct.reservoir().actives(), &output.
literals);
114 case ConstraintProto::ConstraintCase::kTable:
117 case ConstraintProto::ConstraintCase::kAutomaton:
118 AddIndices(
ct.automaton().vars(), &output.
variables);
120 case ConstraintProto::ConstraintCase::kInterval:
121 if (
ct.interval().has_start_view()) {
122 AddIndices(
ct.interval().start_view().vars(), &output.
variables);
126 if (
ct.interval().has_size_view()) {
127 AddIndices(
ct.interval().size_view().vars(), &output.
variables);
131 if (
ct.interval().has_end_view()) {
132 AddIndices(
ct.interval().end_view().vars(), &output.
variables);
137 case ConstraintProto::ConstraintCase::kNoOverlap:
139 case ConstraintProto::ConstraintCase::kNoOverlap2D:
141 case ConstraintProto::ConstraintCase::kCumulative:
142 output.
variables.push_back(
ct.cumulative().capacity());
143 AddIndices(
ct.cumulative().demands(), &output.
variables);
145 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
151 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
153 int temp = ct->mutable_##ct_name()->field_name(); \
155 ct->mutable_##ct_name()->set_##field_name(temp); \
158 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
160 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
164 ConstraintProto*
ct) {
165 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
166 switch (
ct->constraint_case()) {
167 case ConstraintProto::ConstraintCase::kBoolOr:
170 case ConstraintProto::ConstraintCase::kBoolAnd:
173 case ConstraintProto::ConstraintCase::kAtMostOne:
176 case ConstraintProto::ConstraintCase::kBoolXor:
179 case ConstraintProto::ConstraintCase::kIntDiv:
181 case ConstraintProto::ConstraintCase::kIntMod:
183 case ConstraintProto::ConstraintCase::kIntMax:
185 case ConstraintProto::ConstraintCase::kLinMax:
187 case ConstraintProto::ConstraintCase::kIntMin:
189 case ConstraintProto::ConstraintCase::kLinMin:
191 case ConstraintProto::ConstraintCase::kIntProd:
193 case ConstraintProto::ConstraintCase::kLinear:
195 case ConstraintProto::ConstraintCase::kAllDiff:
197 case ConstraintProto::ConstraintCase::kElement:
199 case ConstraintProto::ConstraintCase::kCircuit:
202 case ConstraintProto::ConstraintCase::kRoutes:
205 case ConstraintProto::ConstraintCase::kInverse:
207 case ConstraintProto::ConstraintCase::kReservoir:
210 case ConstraintProto::ConstraintCase::kTable:
212 case ConstraintProto::ConstraintCase::kAutomaton:
214 case ConstraintProto::ConstraintCase::kInterval:
216 case ConstraintProto::ConstraintCase::kNoOverlap:
218 case ConstraintProto::ConstraintCase::kNoOverlap2D:
220 case ConstraintProto::ConstraintCase::kCumulative:
222 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
228 ConstraintProto*
ct) {
229 switch (
ct->constraint_case()) {
230 case ConstraintProto::ConstraintCase::kBoolOr:
232 case ConstraintProto::ConstraintCase::kBoolAnd:
234 case ConstraintProto::ConstraintCase::kAtMostOne:
236 case ConstraintProto::ConstraintCase::kBoolXor:
238 case ConstraintProto::ConstraintCase::kIntDiv:
242 case ConstraintProto::ConstraintCase::kIntMod:
246 case ConstraintProto::ConstraintCase::kIntMax:
250 case ConstraintProto::ConstraintCase::kLinMax:
252 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
256 case ConstraintProto::ConstraintCase::kIntMin:
260 case ConstraintProto::ConstraintCase::kLinMin:
262 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
266 case ConstraintProto::ConstraintCase::kIntProd:
270 case ConstraintProto::ConstraintCase::kLinear:
273 case ConstraintProto::ConstraintCase::kAllDiff:
276 case ConstraintProto::ConstraintCase::kElement:
281 case ConstraintProto::ConstraintCase::kCircuit:
283 case ConstraintProto::ConstraintCase::kRoutes:
285 case ConstraintProto::ConstraintCase::kInverse:
289 case ConstraintProto::ConstraintCase::kReservoir:
292 case ConstraintProto::ConstraintCase::kTable:
295 case ConstraintProto::ConstraintCase::kAutomaton:
298 case ConstraintProto::ConstraintCase::kInterval:
299 if (
ct->interval().has_start_view()) {
304 if (
ct->interval().has_size_view()) {
309 if (
ct->interval().has_end_view()) {
315 case ConstraintProto::ConstraintCase::kNoOverlap:
317 case ConstraintProto::ConstraintCase::kNoOverlap2D:
319 case ConstraintProto::ConstraintCase::kCumulative:
323 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
329 ConstraintProto*
ct) {
330 switch (
ct->constraint_case()) {
331 case ConstraintProto::ConstraintCase::kBoolOr:
333 case ConstraintProto::ConstraintCase::kBoolAnd:
335 case ConstraintProto::ConstraintCase::kAtMostOne:
337 case ConstraintProto::ConstraintCase::kBoolXor:
339 case ConstraintProto::ConstraintCase::kIntDiv:
341 case ConstraintProto::ConstraintCase::kIntMod:
343 case ConstraintProto::ConstraintCase::kIntMax:
345 case ConstraintProto::ConstraintCase::kLinMax:
347 case ConstraintProto::ConstraintCase::kIntMin:
349 case ConstraintProto::ConstraintCase::kLinMin:
351 case ConstraintProto::ConstraintCase::kIntProd:
353 case ConstraintProto::ConstraintCase::kLinear:
355 case ConstraintProto::ConstraintCase::kAllDiff:
357 case ConstraintProto::ConstraintCase::kElement:
359 case ConstraintProto::ConstraintCase::kCircuit:
361 case ConstraintProto::ConstraintCase::kRoutes:
363 case ConstraintProto::ConstraintCase::kInverse:
365 case ConstraintProto::ConstraintCase::kReservoir:
367 case ConstraintProto::ConstraintCase::kTable:
369 case ConstraintProto::ConstraintCase::kAutomaton:
371 case ConstraintProto::ConstraintCase::kInterval:
373 case ConstraintProto::ConstraintCase::kNoOverlap:
376 case ConstraintProto::ConstraintCase::kNoOverlap2D:
380 case ConstraintProto::ConstraintCase::kCumulative:
383 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
388 #undef APPLY_TO_SINGULAR_FIELD
389 #undef APPLY_TO_REPEATED_FIELD
392 ConstraintProto::ConstraintCase constraint_case) {
393 switch (constraint_case) {
394 case ConstraintProto::ConstraintCase::kBoolOr:
396 case ConstraintProto::ConstraintCase::kBoolAnd:
398 case ConstraintProto::ConstraintCase::kAtMostOne:
400 case ConstraintProto::ConstraintCase::kBoolXor:
402 case ConstraintProto::ConstraintCase::kIntDiv:
404 case ConstraintProto::ConstraintCase::kIntMod:
406 case ConstraintProto::ConstraintCase::kIntMax:
408 case ConstraintProto::ConstraintCase::kLinMax:
410 case ConstraintProto::ConstraintCase::kIntMin:
412 case ConstraintProto::ConstraintCase::kLinMin:
414 case ConstraintProto::ConstraintCase::kIntProd:
416 case ConstraintProto::ConstraintCase::kLinear:
418 case ConstraintProto::ConstraintCase::kAllDiff:
420 case ConstraintProto::ConstraintCase::kElement:
422 case ConstraintProto::ConstraintCase::kCircuit:
424 case ConstraintProto::ConstraintCase::kRoutes:
426 case ConstraintProto::ConstraintCase::kInverse:
428 case ConstraintProto::ConstraintCase::kReservoir:
430 case ConstraintProto::ConstraintCase::kTable:
432 case ConstraintProto::ConstraintCase::kAutomaton:
434 case ConstraintProto::ConstraintCase::kInterval:
436 case ConstraintProto::ConstraintCase::kNoOverlap:
438 case ConstraintProto::ConstraintCase::kNoOverlap2D:
439 return "kNoOverlap2D";
440 case ConstraintProto::ConstraintCase::kCumulative:
441 return "kCumulative";
442 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
452 for (
const int lit : references.
literals) {
455 for (
const int lit :
ct.enforcement_literal()) {
463 std::vector<int> used_intervals;
464 switch (
ct.constraint_case()) {
465 case ConstraintProto::ConstraintCase::kBoolOr:
467 case ConstraintProto::ConstraintCase::kBoolAnd:
469 case ConstraintProto::ConstraintCase::kAtMostOne:
471 case ConstraintProto::ConstraintCase::kBoolXor:
473 case ConstraintProto::ConstraintCase::kIntDiv:
475 case ConstraintProto::ConstraintCase::kIntMod:
477 case ConstraintProto::ConstraintCase::kIntMax:
479 case ConstraintProto::ConstraintCase::kLinMax:
481 case ConstraintProto::ConstraintCase::kIntMin:
483 case ConstraintProto::ConstraintCase::kLinMin:
485 case ConstraintProto::ConstraintCase::kIntProd:
487 case ConstraintProto::ConstraintCase::kLinear:
489 case ConstraintProto::ConstraintCase::kAllDiff:
491 case ConstraintProto::ConstraintCase::kElement:
493 case ConstraintProto::ConstraintCase::kCircuit:
495 case ConstraintProto::ConstraintCase::kRoutes:
497 case ConstraintProto::ConstraintCase::kInverse:
499 case ConstraintProto::ConstraintCase::kReservoir:
501 case ConstraintProto::ConstraintCase::kTable:
503 case ConstraintProto::ConstraintCase::kAutomaton:
505 case ConstraintProto::ConstraintCase::kInterval:
507 case ConstraintProto::ConstraintCase::kNoOverlap:
508 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
510 case ConstraintProto::ConstraintCase::kNoOverlap2D:
511 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
512 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
514 case ConstraintProto::ConstraintCase::kCumulative:
515 AddIndices(
ct.cumulative().intervals(), &used_intervals);
517 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
521 return used_intervals;
526 int64 objective_value = 0;
527 auto& repeated_field_values =
response.solution().empty()
530 for (
int i = 0; i < objective.vars_size(); ++i) {
531 int64 coeff = objective.coeffs(i);
532 const int ref = objective.vars(i);
535 objective_value += coeff * repeated_field_values[
var];
537 return objective_value;