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::kInverse:
113 AddIndices(
ct.inverse().f_direct(), &output.
variables);
114 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
116 case ConstraintProto::ConstraintCase::kReservoir:
117 AddIndices(
ct.reservoir().times(), &output.
variables);
118 AddIndices(
ct.reservoir().actives(), &output.
literals);
120 case ConstraintProto::ConstraintCase::kTable:
123 case ConstraintProto::ConstraintCase::kAutomaton:
124 AddIndices(
ct.automaton().vars(), &output.
variables);
126 case ConstraintProto::ConstraintCase::kInterval:
131 case ConstraintProto::ConstraintCase::kNoOverlap:
133 case ConstraintProto::ConstraintCase::kNoOverlap2D:
135 case ConstraintProto::ConstraintCase::kCumulative:
136 output.
variables.push_back(
ct.cumulative().capacity());
137 AddIndices(
ct.cumulative().demands(), &output.
variables);
139 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
145 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
147 int temp = ct->mutable_##ct_name()->field_name(); \
149 ct->mutable_##ct_name()->set_##field_name(temp); \
152 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
154 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
158 ConstraintProto*
ct) {
159 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
160 switch (
ct->constraint_case()) {
161 case ConstraintProto::ConstraintCase::kBoolOr:
164 case ConstraintProto::ConstraintCase::kBoolAnd:
167 case ConstraintProto::ConstraintCase::kAtMostOne:
170 case ConstraintProto::ConstraintCase::kBoolXor:
173 case ConstraintProto::ConstraintCase::kIntDiv:
175 case ConstraintProto::ConstraintCase::kIntMod:
177 case ConstraintProto::ConstraintCase::kIntMax:
179 case ConstraintProto::ConstraintCase::kLinMax:
181 case ConstraintProto::ConstraintCase::kIntMin:
183 case ConstraintProto::ConstraintCase::kLinMin:
185 case ConstraintProto::ConstraintCase::kIntProd:
187 case ConstraintProto::ConstraintCase::kLinear:
189 case ConstraintProto::ConstraintCase::kAllDiff:
191 case ConstraintProto::ConstraintCase::kElement:
193 case ConstraintProto::ConstraintCase::kCircuit:
196 case ConstraintProto::ConstraintCase::kRoutes:
199 case ConstraintProto::ConstraintCase::kInverse:
201 case ConstraintProto::ConstraintCase::kReservoir:
204 case ConstraintProto::ConstraintCase::kTable:
206 case ConstraintProto::ConstraintCase::kAutomaton:
208 case ConstraintProto::ConstraintCase::kInterval:
210 case ConstraintProto::ConstraintCase::kNoOverlap:
212 case ConstraintProto::ConstraintCase::kNoOverlap2D:
214 case ConstraintProto::ConstraintCase::kCumulative:
216 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
222 ConstraintProto*
ct) {
223 switch (
ct->constraint_case()) {
224 case ConstraintProto::ConstraintCase::kBoolOr:
226 case ConstraintProto::ConstraintCase::kBoolAnd:
228 case ConstraintProto::ConstraintCase::kAtMostOne:
230 case ConstraintProto::ConstraintCase::kBoolXor:
232 case ConstraintProto::ConstraintCase::kIntDiv:
236 case ConstraintProto::ConstraintCase::kIntMod:
240 case ConstraintProto::ConstraintCase::kIntMax:
244 case ConstraintProto::ConstraintCase::kLinMax:
246 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
250 case ConstraintProto::ConstraintCase::kIntMin:
254 case ConstraintProto::ConstraintCase::kLinMin:
256 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
260 case ConstraintProto::ConstraintCase::kIntProd:
264 case ConstraintProto::ConstraintCase::kLinear:
267 case ConstraintProto::ConstraintCase::kAllDiff:
270 case ConstraintProto::ConstraintCase::kElement:
275 case ConstraintProto::ConstraintCase::kCircuit:
277 case ConstraintProto::ConstraintCase::kRoutes:
279 case ConstraintProto::ConstraintCase::kInverse:
283 case ConstraintProto::ConstraintCase::kReservoir:
286 case ConstraintProto::ConstraintCase::kTable:
289 case ConstraintProto::ConstraintCase::kAutomaton:
292 case ConstraintProto::ConstraintCase::kInterval:
297 case ConstraintProto::ConstraintCase::kNoOverlap:
299 case ConstraintProto::ConstraintCase::kNoOverlap2D:
301 case ConstraintProto::ConstraintCase::kCumulative:
305 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
311 ConstraintProto*
ct) {
312 switch (
ct->constraint_case()) {
313 case ConstraintProto::ConstraintCase::kBoolOr:
315 case ConstraintProto::ConstraintCase::kBoolAnd:
317 case ConstraintProto::ConstraintCase::kAtMostOne:
319 case ConstraintProto::ConstraintCase::kBoolXor:
321 case ConstraintProto::ConstraintCase::kIntDiv:
323 case ConstraintProto::ConstraintCase::kIntMod:
325 case ConstraintProto::ConstraintCase::kIntMax:
327 case ConstraintProto::ConstraintCase::kLinMax:
329 case ConstraintProto::ConstraintCase::kIntMin:
331 case ConstraintProto::ConstraintCase::kLinMin:
333 case ConstraintProto::ConstraintCase::kIntProd:
335 case ConstraintProto::ConstraintCase::kLinear:
337 case ConstraintProto::ConstraintCase::kAllDiff:
339 case ConstraintProto::ConstraintCase::kElement:
341 case ConstraintProto::ConstraintCase::kCircuit:
343 case ConstraintProto::ConstraintCase::kRoutes:
345 case ConstraintProto::ConstraintCase::kInverse:
347 case ConstraintProto::ConstraintCase::kReservoir:
349 case ConstraintProto::ConstraintCase::kTable:
351 case ConstraintProto::ConstraintCase::kAutomaton:
353 case ConstraintProto::ConstraintCase::kInterval:
355 case ConstraintProto::ConstraintCase::kNoOverlap:
358 case ConstraintProto::ConstraintCase::kNoOverlap2D:
362 case ConstraintProto::ConstraintCase::kCumulative:
365 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
370 #undef APPLY_TO_SINGULAR_FIELD
371 #undef APPLY_TO_REPEATED_FIELD
374 ConstraintProto::ConstraintCase constraint_case) {
375 switch (constraint_case) {
376 case ConstraintProto::ConstraintCase::kBoolOr:
378 case ConstraintProto::ConstraintCase::kBoolAnd:
380 case ConstraintProto::ConstraintCase::kAtMostOne:
382 case ConstraintProto::ConstraintCase::kBoolXor:
384 case ConstraintProto::ConstraintCase::kIntDiv:
386 case ConstraintProto::ConstraintCase::kIntMod:
388 case ConstraintProto::ConstraintCase::kIntMax:
390 case ConstraintProto::ConstraintCase::kLinMax:
392 case ConstraintProto::ConstraintCase::kIntMin:
394 case ConstraintProto::ConstraintCase::kLinMin:
396 case ConstraintProto::ConstraintCase::kIntProd:
398 case ConstraintProto::ConstraintCase::kLinear:
400 case ConstraintProto::ConstraintCase::kAllDiff:
402 case ConstraintProto::ConstraintCase::kElement:
404 case ConstraintProto::ConstraintCase::kCircuit:
406 case ConstraintProto::ConstraintCase::kRoutes:
408 case ConstraintProto::ConstraintCase::kInverse:
410 case ConstraintProto::ConstraintCase::kReservoir:
412 case ConstraintProto::ConstraintCase::kTable:
414 case ConstraintProto::ConstraintCase::kAutomaton:
416 case ConstraintProto::ConstraintCase::kInterval:
418 case ConstraintProto::ConstraintCase::kNoOverlap:
420 case ConstraintProto::ConstraintCase::kNoOverlap2D:
421 return "kNoOverlap2D";
422 case ConstraintProto::ConstraintCase::kCumulative:
423 return "kCumulative";
424 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
434 for (
const int lit : references.
literals) {
437 for (
const int lit :
ct.enforcement_literal()) {
445 std::vector<int> used_intervals;
446 switch (
ct.constraint_case()) {
447 case ConstraintProto::ConstraintCase::kBoolOr:
449 case ConstraintProto::ConstraintCase::kBoolAnd:
451 case ConstraintProto::ConstraintCase::kAtMostOne:
453 case ConstraintProto::ConstraintCase::kBoolXor:
455 case ConstraintProto::ConstraintCase::kIntDiv:
457 case ConstraintProto::ConstraintCase::kIntMod:
459 case ConstraintProto::ConstraintCase::kIntMax:
461 case ConstraintProto::ConstraintCase::kLinMax:
463 case ConstraintProto::ConstraintCase::kIntMin:
465 case ConstraintProto::ConstraintCase::kLinMin:
467 case ConstraintProto::ConstraintCase::kIntProd:
469 case ConstraintProto::ConstraintCase::kLinear:
471 case ConstraintProto::ConstraintCase::kAllDiff:
473 case ConstraintProto::ConstraintCase::kElement:
475 case ConstraintProto::ConstraintCase::kCircuit:
477 case ConstraintProto::ConstraintCase::kRoutes:
479 case ConstraintProto::ConstraintCase::kInverse:
481 case ConstraintProto::ConstraintCase::kReservoir:
483 case ConstraintProto::ConstraintCase::kTable:
485 case ConstraintProto::ConstraintCase::kAutomaton:
487 case ConstraintProto::ConstraintCase::kInterval:
489 case ConstraintProto::ConstraintCase::kNoOverlap:
490 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
492 case ConstraintProto::ConstraintCase::kNoOverlap2D:
493 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
494 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
496 case ConstraintProto::ConstraintCase::kCumulative:
497 AddIndices(
ct.cumulative().intervals(), &used_intervals);
499 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
503 return used_intervals;
508 int64 objective_value = 0;
509 auto& repeated_field_values =
response.solution().empty()
512 for (
int i = 0; i < objective.vars_size(); ++i) {
513 int64 coeff = objective.coeffs(i);
514 const int ref = objective.vars(i);
517 objective_value += coeff * repeated_field_values[
var];
519 return objective_value;