27template <
typename IntList>
28void AddIndices(
const IntList& indices, std::vector<int>* output) {
29 output->insert(output->end(), indices.begin(), indices.end());
36 output_negated_expr->
Clear();
37 for (
int i = 0; i < input_expr.
vars_size(); ++i) {
46 switch (
ct.constraint_case()) {
47 case ConstraintProto::ConstraintCase::kBoolOr:
48 AddIndices(
ct.bool_or().literals(), &output.
literals);
50 case ConstraintProto::ConstraintCase::kBoolAnd:
51 AddIndices(
ct.bool_and().literals(), &output.
literals);
53 case ConstraintProto::ConstraintCase::kAtMostOne:
54 AddIndices(
ct.at_most_one().literals(), &output.
literals);
56 case ConstraintProto::ConstraintCase::kExactlyOne:
57 AddIndices(
ct.exactly_one().literals(), &output.
literals);
59 case ConstraintProto::ConstraintCase::kBoolXor:
60 AddIndices(
ct.bool_xor().literals(), &output.
literals);
62 case ConstraintProto::ConstraintCase::kIntDiv:
66 case ConstraintProto::ConstraintCase::kIntMod:
70 case ConstraintProto::ConstraintCase::kIntMax:
74 case ConstraintProto::ConstraintCase::kLinMax: {
75 AddIndices(
ct.lin_max().target().vars(), &output.
variables);
76 for (
int i = 0; i <
ct.lin_max().exprs_size(); ++i) {
77 AddIndices(
ct.lin_max().exprs(i).vars(), &output.
variables);
81 case ConstraintProto::ConstraintCase::kIntMin:
85 case ConstraintProto::ConstraintCase::kLinMin: {
86 AddIndices(
ct.lin_min().target().vars(), &output.
variables);
87 for (
int i = 0; i <
ct.lin_min().exprs_size(); ++i) {
88 AddIndices(
ct.lin_min().exprs(i).vars(), &output.
variables);
92 case ConstraintProto::ConstraintCase::kIntProd:
94 AddIndices(
ct.int_prod().vars(), &output.
variables);
96 case ConstraintProto::ConstraintCase::kLinear:
99 case ConstraintProto::ConstraintCase::kAllDiff:
100 AddIndices(
ct.all_diff().vars(), &output.
variables);
102 case ConstraintProto::ConstraintCase::kDummyConstraint:
103 AddIndices(
ct.dummy_constraint().vars(), &output.
variables);
105 case ConstraintProto::ConstraintCase::kElement:
108 AddIndices(
ct.element().vars(), &output.
variables);
110 case ConstraintProto::ConstraintCase::kCircuit:
111 AddIndices(
ct.circuit().literals(), &output.
literals);
113 case ConstraintProto::ConstraintCase::kRoutes:
114 AddIndices(
ct.routes().literals(), &output.
literals);
116 case ConstraintProto::ConstraintCase::kInverse:
117 AddIndices(
ct.inverse().f_direct(), &output.
variables);
118 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
120 case ConstraintProto::ConstraintCase::kReservoir:
121 AddIndices(
ct.reservoir().times(), &output.
variables);
122 AddIndices(
ct.reservoir().actives(), &output.
literals);
124 case ConstraintProto::ConstraintCase::kTable:
127 case ConstraintProto::ConstraintCase::kAutomaton:
128 AddIndices(
ct.automaton().vars(), &output.
variables);
130 case ConstraintProto::ConstraintCase::kInterval:
131 if (
ct.interval().has_start_view()) {
132 AddIndices(
ct.interval().start_view().vars(), &output.
variables);
136 if (
ct.interval().has_size_view()) {
137 AddIndices(
ct.interval().size_view().vars(), &output.
variables);
141 if (
ct.interval().has_end_view()) {
142 AddIndices(
ct.interval().end_view().vars(), &output.
variables);
147 case ConstraintProto::ConstraintCase::kNoOverlap:
149 case ConstraintProto::ConstraintCase::kNoOverlap2D:
151 case ConstraintProto::ConstraintCase::kCumulative:
152 output.
variables.push_back(
ct.cumulative().capacity());
153 AddIndices(
ct.cumulative().demands(), &output.
variables);
155 AddIndices(lin.vars(), &output.
variables);
158 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
164#define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
166 int temp = ct->mutable_##ct_name()->field_name(); \
168 ct->mutable_##ct_name()->set_##field_name(temp); \
171#define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
173 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
178 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
179 switch (
ct->constraint_case()) {
180 case ConstraintProto::ConstraintCase::kBoolOr:
183 case ConstraintProto::ConstraintCase::kBoolAnd:
186 case ConstraintProto::ConstraintCase::kAtMostOne:
189 case ConstraintProto::ConstraintCase::kExactlyOne:
192 case ConstraintProto::ConstraintCase::kBoolXor:
195 case ConstraintProto::ConstraintCase::kIntDiv:
197 case ConstraintProto::ConstraintCase::kIntMod:
199 case ConstraintProto::ConstraintCase::kIntMax:
201 case ConstraintProto::ConstraintCase::kLinMax:
203 case ConstraintProto::ConstraintCase::kIntMin:
205 case ConstraintProto::ConstraintCase::kLinMin:
207 case ConstraintProto::ConstraintCase::kIntProd:
209 case ConstraintProto::ConstraintCase::kLinear:
211 case ConstraintProto::ConstraintCase::kAllDiff:
213 case ConstraintProto::ConstraintCase::kDummyConstraint:
215 case ConstraintProto::ConstraintCase::kElement:
217 case ConstraintProto::ConstraintCase::kCircuit:
220 case ConstraintProto::ConstraintCase::kRoutes:
223 case ConstraintProto::ConstraintCase::kInverse:
225 case ConstraintProto::ConstraintCase::kReservoir:
228 case ConstraintProto::ConstraintCase::kTable:
230 case ConstraintProto::ConstraintCase::kAutomaton:
232 case ConstraintProto::ConstraintCase::kInterval:
234 case ConstraintProto::ConstraintCase::kNoOverlap:
236 case ConstraintProto::ConstraintCase::kNoOverlap2D:
238 case ConstraintProto::ConstraintCase::kCumulative:
240 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
247 switch (
ct->constraint_case()) {
248 case ConstraintProto::ConstraintCase::kBoolOr:
250 case ConstraintProto::ConstraintCase::kBoolAnd:
252 case ConstraintProto::ConstraintCase::kAtMostOne:
254 case ConstraintProto::ConstraintCase::kExactlyOne:
256 case ConstraintProto::ConstraintCase::kBoolXor:
258 case ConstraintProto::ConstraintCase::kIntDiv:
262 case ConstraintProto::ConstraintCase::kIntMod:
266 case ConstraintProto::ConstraintCase::kIntMax:
270 case ConstraintProto::ConstraintCase::kLinMax:
272 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
276 case ConstraintProto::ConstraintCase::kIntMin:
280 case ConstraintProto::ConstraintCase::kLinMin:
282 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
286 case ConstraintProto::ConstraintCase::kIntProd:
290 case ConstraintProto::ConstraintCase::kLinear:
293 case ConstraintProto::ConstraintCase::kAllDiff:
296 case ConstraintProto::ConstraintCase::kDummyConstraint:
299 case ConstraintProto::ConstraintCase::kElement:
304 case ConstraintProto::ConstraintCase::kCircuit:
306 case ConstraintProto::ConstraintCase::kRoutes:
308 case ConstraintProto::ConstraintCase::kInverse:
312 case ConstraintProto::ConstraintCase::kReservoir:
315 case ConstraintProto::ConstraintCase::kTable:
318 case ConstraintProto::ConstraintCase::kAutomaton:
321 case ConstraintProto::ConstraintCase::kInterval:
322 if (
ct->interval().has_start_view()) {
327 if (
ct->interval().has_size_view()) {
332 if (
ct->interval().has_end_view()) {
338 case ConstraintProto::ConstraintCase::kNoOverlap:
340 case ConstraintProto::ConstraintCase::kNoOverlap2D:
342 case ConstraintProto::ConstraintCase::kCumulative:
345 for (
int i = 0; i <
ct->cumulative().energies_size(); ++i) {
347 *
ct->mutable_cumulative()->mutable_energies(i)->mutable_vars()) {
352 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
359 switch (
ct->constraint_case()) {
360 case ConstraintProto::ConstraintCase::kBoolOr:
362 case ConstraintProto::ConstraintCase::kBoolAnd:
364 case ConstraintProto::ConstraintCase::kAtMostOne:
366 case ConstraintProto::ConstraintCase::kExactlyOne:
368 case ConstraintProto::ConstraintCase::kBoolXor:
370 case ConstraintProto::ConstraintCase::kIntDiv:
372 case ConstraintProto::ConstraintCase::kIntMod:
374 case ConstraintProto::ConstraintCase::kIntMax:
376 case ConstraintProto::ConstraintCase::kLinMax:
378 case ConstraintProto::ConstraintCase::kIntMin:
380 case ConstraintProto::ConstraintCase::kLinMin:
382 case ConstraintProto::ConstraintCase::kIntProd:
384 case ConstraintProto::ConstraintCase::kLinear:
386 case ConstraintProto::ConstraintCase::kAllDiff:
388 case ConstraintProto::ConstraintCase::kDummyConstraint:
390 case ConstraintProto::ConstraintCase::kElement:
392 case ConstraintProto::ConstraintCase::kCircuit:
394 case ConstraintProto::ConstraintCase::kRoutes:
396 case ConstraintProto::ConstraintCase::kInverse:
398 case ConstraintProto::ConstraintCase::kReservoir:
400 case ConstraintProto::ConstraintCase::kTable:
402 case ConstraintProto::ConstraintCase::kAutomaton:
404 case ConstraintProto::ConstraintCase::kInterval:
406 case ConstraintProto::ConstraintCase::kNoOverlap:
409 case ConstraintProto::ConstraintCase::kNoOverlap2D:
413 case ConstraintProto::ConstraintCase::kCumulative:
416 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
421#undef APPLY_TO_SINGULAR_FIELD
422#undef APPLY_TO_REPEATED_FIELD
426 switch (constraint_case) {
427 case ConstraintProto::ConstraintCase::kBoolOr:
429 case ConstraintProto::ConstraintCase::kBoolAnd:
431 case ConstraintProto::ConstraintCase::kAtMostOne:
433 case ConstraintProto::ConstraintCase::kExactlyOne:
434 return "kExactlyOne";
435 case ConstraintProto::ConstraintCase::kBoolXor:
437 case ConstraintProto::ConstraintCase::kIntDiv:
439 case ConstraintProto::ConstraintCase::kIntMod:
441 case ConstraintProto::ConstraintCase::kIntMax:
443 case ConstraintProto::ConstraintCase::kLinMax:
445 case ConstraintProto::ConstraintCase::kIntMin:
447 case ConstraintProto::ConstraintCase::kLinMin:
449 case ConstraintProto::ConstraintCase::kIntProd:
451 case ConstraintProto::ConstraintCase::kLinear:
453 case ConstraintProto::ConstraintCase::kAllDiff:
455 case ConstraintProto::ConstraintCase::kDummyConstraint:
456 return "kDummyConstraint";
457 case ConstraintProto::ConstraintCase::kElement:
459 case ConstraintProto::ConstraintCase::kCircuit:
461 case ConstraintProto::ConstraintCase::kRoutes:
463 case ConstraintProto::ConstraintCase::kInverse:
465 case ConstraintProto::ConstraintCase::kReservoir:
467 case ConstraintProto::ConstraintCase::kTable:
469 case ConstraintProto::ConstraintCase::kAutomaton:
471 case ConstraintProto::ConstraintCase::kInterval:
473 case ConstraintProto::ConstraintCase::kNoOverlap:
475 case ConstraintProto::ConstraintCase::kNoOverlap2D:
476 return "kNoOverlap2D";
477 case ConstraintProto::ConstraintCase::kCumulative:
478 return "kCumulative";
479 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
489 for (
const int lit : references.
literals) {
492 for (
const int lit :
ct.enforcement_literal()) {
500 std::vector<int> used_intervals;
501 switch (
ct.constraint_case()) {
502 case ConstraintProto::ConstraintCase::kBoolOr:
504 case ConstraintProto::ConstraintCase::kBoolAnd:
506 case ConstraintProto::ConstraintCase::kAtMostOne:
508 case ConstraintProto::ConstraintCase::kExactlyOne:
510 case ConstraintProto::ConstraintCase::kBoolXor:
512 case ConstraintProto::ConstraintCase::kIntDiv:
514 case ConstraintProto::ConstraintCase::kIntMod:
516 case ConstraintProto::ConstraintCase::kIntMax:
518 case ConstraintProto::ConstraintCase::kLinMax:
520 case ConstraintProto::ConstraintCase::kIntMin:
522 case ConstraintProto::ConstraintCase::kLinMin:
524 case ConstraintProto::ConstraintCase::kIntProd:
526 case ConstraintProto::ConstraintCase::kLinear:
528 case ConstraintProto::ConstraintCase::kAllDiff:
530 case ConstraintProto::ConstraintCase::kDummyConstraint:
532 case ConstraintProto::ConstraintCase::kElement:
534 case ConstraintProto::ConstraintCase::kCircuit:
536 case ConstraintProto::ConstraintCase::kRoutes:
538 case ConstraintProto::ConstraintCase::kInverse:
540 case ConstraintProto::ConstraintCase::kReservoir:
542 case ConstraintProto::ConstraintCase::kTable:
544 case ConstraintProto::ConstraintCase::kAutomaton:
546 case ConstraintProto::ConstraintCase::kInterval:
548 case ConstraintProto::ConstraintCase::kNoOverlap:
549 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
551 case ConstraintProto::ConstraintCase::kNoOverlap2D:
552 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
553 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
555 case ConstraintProto::ConstraintCase::kCumulative:
556 AddIndices(
ct.cumulative().intervals(), &used_intervals);
558 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
562 return used_intervals;
567 int64_t objective_value = 0;
568 auto& repeated_field_values =
response.solution().empty()
571 for (
int i = 0; i < objective.
vars_size(); ++i) {
572 int64_t coeff = objective.
coeffs(i);
573 const int ref = objective.
vars(i);
576 objective_value += coeff * repeated_field_values[
var];
578 return objective_value;
::PROTOBUF_NAMESPACE_ID::int64 coeffs(int index) const
::PROTOBUF_NAMESPACE_ID::int32 vars(int index) const
::PROTOBUF_NAMESPACE_ID::int64 coeffs(int index) const
::PROTOBUF_NAMESPACE_ID::int64 offset() const
void set_offset(::PROTOBUF_NAMESPACE_ID::int64 value)
void add_coeffs(::PROTOBUF_NAMESPACE_ID::int64 value)
PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final
::PROTOBUF_NAMESPACE_ID::int32 vars(int index) const
void add_vars(::PROTOBUF_NAMESPACE_ID::int32 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)
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)
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)
Collection of objects used to extend the Constraint Solver library.
std::vector< int > variables
std::vector< int > literals