16 #include "absl/container/flat_hash_set.h"
24 template <
typename IntList>
25 void AddIndices(
const IntList& indices, absl::flat_hash_set<int>* output) {
26 output->insert(indices.begin(), indices.end());
29 template <
typename IntList>
30 void AddIndices(
const IntList& indices, std::vector<int>* output) {
31 output->insert(output->end(), indices.begin(), indices.end());
37 LinearExpressionProto* output_negated_expr) {
38 output_negated_expr->Clear();
39 for (
int i = 0; i < input_expr.vars_size(); ++i) {
40 output_negated_expr->add_vars(
NegatedRef(input_expr.vars(i)));
41 output_negated_expr->add_coeffs(input_expr.coeffs(i));
43 output_negated_expr->set_offset(-input_expr.offset());
48 switch (
ct.constraint_case()) {
49 case ConstraintProto::ConstraintCase::kBoolOr:
50 AddIndices(
ct.bool_or().literals(), &output.
literals);
52 case ConstraintProto::ConstraintCase::kBoolAnd:
53 AddIndices(
ct.bool_and().literals(), &output.
literals);
55 case ConstraintProto::ConstraintCase::kAtMostOne:
56 AddIndices(
ct.at_most_one().literals(), &output.
literals);
58 case ConstraintProto::ConstraintCase::kBoolXor:
59 AddIndices(
ct.bool_xor().literals(), &output.
literals);
61 case ConstraintProto::ConstraintCase::kIntDiv:
65 case ConstraintProto::ConstraintCase::kIntMod:
69 case ConstraintProto::ConstraintCase::kIntMax:
73 case ConstraintProto::ConstraintCase::kLinMax: {
74 AddIndices(
ct.lin_max().target().vars(), &output.
variables);
75 for (
int i = 0; i <
ct.lin_max().exprs_size(); ++i) {
76 AddIndices(
ct.lin_max().exprs(i).vars(), &output.
variables);
80 case ConstraintProto::ConstraintCase::kIntMin:
84 case ConstraintProto::ConstraintCase::kLinMin: {
85 AddIndices(
ct.lin_min().target().vars(), &output.
variables);
86 for (
int i = 0; i <
ct.lin_min().exprs_size(); ++i) {
87 AddIndices(
ct.lin_min().exprs(i).vars(), &output.
variables);
91 case ConstraintProto::ConstraintCase::kIntProd:
93 AddIndices(
ct.int_prod().vars(), &output.
variables);
95 case ConstraintProto::ConstraintCase::kLinear:
98 case ConstraintProto::ConstraintCase::kAllDiff:
99 AddIndices(
ct.all_diff().vars(), &output.
variables);
101 case ConstraintProto::ConstraintCase::kElement:
104 AddIndices(
ct.element().vars(), &output.
variables);
106 case ConstraintProto::ConstraintCase::kCircuit:
107 AddIndices(
ct.circuit().literals(), &output.
literals);
109 case ConstraintProto::ConstraintCase::kRoutes:
110 AddIndices(
ct.routes().literals(), &output.
literals);
112 case ConstraintProto::ConstraintCase::kCircuitCovering:
113 AddIndices(
ct.circuit_covering().nexts(), &output.
variables);
115 case ConstraintProto::ConstraintCase::kInverse:
116 AddIndices(
ct.inverse().f_direct(), &output.
variables);
117 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
119 case ConstraintProto::ConstraintCase::kReservoir:
120 AddIndices(
ct.reservoir().times(), &output.
variables);
121 AddIndices(
ct.reservoir().actives(), &output.
literals);
123 case ConstraintProto::ConstraintCase::kTable:
126 case ConstraintProto::ConstraintCase::kAutomaton:
127 AddIndices(
ct.automaton().vars(), &output.
variables);
129 case ConstraintProto::ConstraintCase::kInterval:
134 case ConstraintProto::ConstraintCase::kNoOverlap:
136 case ConstraintProto::ConstraintCase::kNoOverlap2D:
138 case ConstraintProto::ConstraintCase::kCumulative:
139 output.
variables.push_back(
ct.cumulative().capacity());
140 AddIndices(
ct.cumulative().demands(), &output.
variables);
142 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
148 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
150 int temp = ct->mutable_##ct_name()->field_name(); \
152 ct->mutable_##ct_name()->set_##field_name(temp); \
155 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
157 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
161 ConstraintProto*
ct) {
162 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
163 switch (
ct->constraint_case()) {
164 case ConstraintProto::ConstraintCase::kBoolOr:
167 case ConstraintProto::ConstraintCase::kBoolAnd:
170 case ConstraintProto::ConstraintCase::kAtMostOne:
173 case ConstraintProto::ConstraintCase::kBoolXor:
176 case ConstraintProto::ConstraintCase::kIntDiv:
178 case ConstraintProto::ConstraintCase::kIntMod:
180 case ConstraintProto::ConstraintCase::kIntMax:
182 case ConstraintProto::ConstraintCase::kLinMax:
184 case ConstraintProto::ConstraintCase::kIntMin:
186 case ConstraintProto::ConstraintCase::kLinMin:
188 case ConstraintProto::ConstraintCase::kIntProd:
190 case ConstraintProto::ConstraintCase::kLinear:
192 case ConstraintProto::ConstraintCase::kAllDiff:
194 case ConstraintProto::ConstraintCase::kElement:
196 case ConstraintProto::ConstraintCase::kCircuit:
199 case ConstraintProto::ConstraintCase::kRoutes:
202 case ConstraintProto::ConstraintCase::kCircuitCovering:
204 case ConstraintProto::ConstraintCase::kInverse:
206 case ConstraintProto::ConstraintCase::kReservoir:
209 case ConstraintProto::ConstraintCase::kTable:
211 case ConstraintProto::ConstraintCase::kAutomaton:
213 case ConstraintProto::ConstraintCase::kInterval:
215 case ConstraintProto::ConstraintCase::kNoOverlap:
217 case ConstraintProto::ConstraintCase::kNoOverlap2D:
219 case ConstraintProto::ConstraintCase::kCumulative:
221 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
227 ConstraintProto*
ct) {
228 switch (
ct->constraint_case()) {
229 case ConstraintProto::ConstraintCase::kBoolOr:
231 case ConstraintProto::ConstraintCase::kBoolAnd:
233 case ConstraintProto::ConstraintCase::kAtMostOne:
235 case ConstraintProto::ConstraintCase::kBoolXor:
237 case ConstraintProto::ConstraintCase::kIntDiv:
241 case ConstraintProto::ConstraintCase::kIntMod:
245 case ConstraintProto::ConstraintCase::kIntMax:
249 case ConstraintProto::ConstraintCase::kLinMax:
251 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
255 case ConstraintProto::ConstraintCase::kIntMin:
259 case ConstraintProto::ConstraintCase::kLinMin:
261 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
265 case ConstraintProto::ConstraintCase::kIntProd:
269 case ConstraintProto::ConstraintCase::kLinear:
272 case ConstraintProto::ConstraintCase::kAllDiff:
275 case ConstraintProto::ConstraintCase::kElement:
280 case ConstraintProto::ConstraintCase::kCircuit:
282 case ConstraintProto::ConstraintCase::kRoutes:
284 case ConstraintProto::ConstraintCase::kCircuitCovering:
287 case ConstraintProto::ConstraintCase::kInverse:
291 case ConstraintProto::ConstraintCase::kReservoir:
294 case ConstraintProto::ConstraintCase::kTable:
297 case ConstraintProto::ConstraintCase::kAutomaton:
300 case ConstraintProto::ConstraintCase::kInterval:
305 case ConstraintProto::ConstraintCase::kNoOverlap:
307 case ConstraintProto::ConstraintCase::kNoOverlap2D:
309 case ConstraintProto::ConstraintCase::kCumulative:
313 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
319 ConstraintProto*
ct) {
320 switch (
ct->constraint_case()) {
321 case ConstraintProto::ConstraintCase::kBoolOr:
323 case ConstraintProto::ConstraintCase::kBoolAnd:
325 case ConstraintProto::ConstraintCase::kAtMostOne:
327 case ConstraintProto::ConstraintCase::kBoolXor:
329 case ConstraintProto::ConstraintCase::kIntDiv:
331 case ConstraintProto::ConstraintCase::kIntMod:
333 case ConstraintProto::ConstraintCase::kIntMax:
335 case ConstraintProto::ConstraintCase::kLinMax:
337 case ConstraintProto::ConstraintCase::kIntMin:
339 case ConstraintProto::ConstraintCase::kLinMin:
341 case ConstraintProto::ConstraintCase::kIntProd:
343 case ConstraintProto::ConstraintCase::kLinear:
345 case ConstraintProto::ConstraintCase::kAllDiff:
347 case ConstraintProto::ConstraintCase::kElement:
349 case ConstraintProto::ConstraintCase::kCircuit:
351 case ConstraintProto::ConstraintCase::kRoutes:
353 case ConstraintProto::ConstraintCase::kCircuitCovering:
355 case ConstraintProto::ConstraintCase::kInverse:
357 case ConstraintProto::ConstraintCase::kReservoir:
359 case ConstraintProto::ConstraintCase::kTable:
361 case ConstraintProto::ConstraintCase::kAutomaton:
363 case ConstraintProto::ConstraintCase::kInterval:
365 case ConstraintProto::ConstraintCase::kNoOverlap:
368 case ConstraintProto::ConstraintCase::kNoOverlap2D:
372 case ConstraintProto::ConstraintCase::kCumulative:
375 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
380 #undef APPLY_TO_SINGULAR_FIELD
381 #undef APPLY_TO_REPEATED_FIELD
384 ConstraintProto::ConstraintCase constraint_case) {
385 switch (constraint_case) {
386 case ConstraintProto::ConstraintCase::kBoolOr:
388 case ConstraintProto::ConstraintCase::kBoolAnd:
390 case ConstraintProto::ConstraintCase::kAtMostOne:
392 case ConstraintProto::ConstraintCase::kBoolXor:
394 case ConstraintProto::ConstraintCase::kIntDiv:
396 case ConstraintProto::ConstraintCase::kIntMod:
398 case ConstraintProto::ConstraintCase::kIntMax:
400 case ConstraintProto::ConstraintCase::kLinMax:
402 case ConstraintProto::ConstraintCase::kIntMin:
404 case ConstraintProto::ConstraintCase::kLinMin:
406 case ConstraintProto::ConstraintCase::kIntProd:
408 case ConstraintProto::ConstraintCase::kLinear:
410 case ConstraintProto::ConstraintCase::kAllDiff:
412 case ConstraintProto::ConstraintCase::kElement:
414 case ConstraintProto::ConstraintCase::kCircuit:
416 case ConstraintProto::ConstraintCase::kRoutes:
418 case ConstraintProto::ConstraintCase::kCircuitCovering:
419 return "kCircuitCovering";
420 case ConstraintProto::ConstraintCase::kInverse:
422 case ConstraintProto::ConstraintCase::kReservoir:
424 case ConstraintProto::ConstraintCase::kTable:
426 case ConstraintProto::ConstraintCase::kAutomaton:
428 case ConstraintProto::ConstraintCase::kInterval:
430 case ConstraintProto::ConstraintCase::kNoOverlap:
432 case ConstraintProto::ConstraintCase::kNoOverlap2D:
433 return "kNoOverlap2D";
434 case ConstraintProto::ConstraintCase::kCumulative:
435 return "kCumulative";
436 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
446 for (
const int lit : references.
literals) {
449 for (
const int lit :
ct.enforcement_literal()) {
457 std::vector<int> used_intervals;
458 switch (
ct.constraint_case()) {
459 case ConstraintProto::ConstraintCase::kBoolOr:
461 case ConstraintProto::ConstraintCase::kBoolAnd:
463 case ConstraintProto::ConstraintCase::kAtMostOne:
465 case ConstraintProto::ConstraintCase::kBoolXor:
467 case ConstraintProto::ConstraintCase::kIntDiv:
469 case ConstraintProto::ConstraintCase::kIntMod:
471 case ConstraintProto::ConstraintCase::kIntMax:
473 case ConstraintProto::ConstraintCase::kLinMax:
475 case ConstraintProto::ConstraintCase::kIntMin:
477 case ConstraintProto::ConstraintCase::kLinMin:
479 case ConstraintProto::ConstraintCase::kIntProd:
481 case ConstraintProto::ConstraintCase::kLinear:
483 case ConstraintProto::ConstraintCase::kAllDiff:
485 case ConstraintProto::ConstraintCase::kElement:
487 case ConstraintProto::ConstraintCase::kCircuit:
489 case ConstraintProto::ConstraintCase::kRoutes:
491 case ConstraintProto::ConstraintCase::kCircuitCovering:
493 case ConstraintProto::ConstraintCase::kInverse:
495 case ConstraintProto::ConstraintCase::kReservoir:
497 case ConstraintProto::ConstraintCase::kTable:
499 case ConstraintProto::ConstraintCase::kAutomaton:
501 case ConstraintProto::ConstraintCase::kInterval:
503 case ConstraintProto::ConstraintCase::kNoOverlap:
504 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
506 case ConstraintProto::ConstraintCase::kNoOverlap2D:
507 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
508 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
510 case ConstraintProto::ConstraintCase::kCumulative:
511 AddIndices(
ct.cumulative().intervals(), &used_intervals);
513 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
517 return used_intervals;
522 int64 objective_value = 0;
523 auto& repeated_field_values =
response.solution().empty()
526 for (
int i = 0; i < objective.vars_size(); ++i) {
527 int64 coeff = objective.coeffs(i);
528 const int ref = objective.vars(i);
531 objective_value += coeff * repeated_field_values[
var];
533 return objective_value;