25 template <
typename IntList>
26 void AddIndices(
const IntList& indices, std::vector<int>* output) {
27 output->insert(output->end(), indices.begin(), indices.end());
33 LinearExpressionProto* output_negated_expr) {
34 output_negated_expr->Clear();
35 for (
int i = 0; i < input_expr.vars_size(); ++i) {
36 output_negated_expr->add_vars(
NegatedRef(input_expr.vars(i)));
37 output_negated_expr->add_coeffs(input_expr.coeffs(i));
39 output_negated_expr->set_offset(-input_expr.offset());
44 switch (
ct.constraint_case()) {
45 case ConstraintProto::ConstraintCase::kBoolOr:
46 AddIndices(
ct.bool_or().literals(), &output.
literals);
48 case ConstraintProto::ConstraintCase::kBoolAnd:
49 AddIndices(
ct.bool_and().literals(), &output.
literals);
51 case ConstraintProto::ConstraintCase::kAtMostOne:
52 AddIndices(
ct.at_most_one().literals(), &output.
literals);
54 case ConstraintProto::ConstraintCase::kExactlyOne:
55 AddIndices(
ct.exactly_one().literals(), &output.
literals);
57 case ConstraintProto::ConstraintCase::kBoolXor:
58 AddIndices(
ct.bool_xor().literals(), &output.
literals);
60 case ConstraintProto::ConstraintCase::kIntDiv:
64 case ConstraintProto::ConstraintCase::kIntMod:
68 case ConstraintProto::ConstraintCase::kIntMax:
72 case ConstraintProto::ConstraintCase::kLinMax: {
73 AddIndices(
ct.lin_max().target().vars(), &output.
variables);
74 for (
int i = 0; i <
ct.lin_max().exprs_size(); ++i) {
75 AddIndices(
ct.lin_max().exprs(i).vars(), &output.
variables);
79 case ConstraintProto::ConstraintCase::kIntMin:
83 case ConstraintProto::ConstraintCase::kLinMin: {
84 AddIndices(
ct.lin_min().target().vars(), &output.
variables);
85 for (
int i = 0; i <
ct.lin_min().exprs_size(); ++i) {
86 AddIndices(
ct.lin_min().exprs(i).vars(), &output.
variables);
90 case ConstraintProto::ConstraintCase::kIntProd:
92 AddIndices(
ct.int_prod().vars(), &output.
variables);
94 case ConstraintProto::ConstraintCase::kLinear:
97 case ConstraintProto::ConstraintCase::kAllDiff:
98 AddIndices(
ct.all_diff().vars(), &output.
variables);
100 case ConstraintProto::ConstraintCase::kElement:
103 AddIndices(
ct.element().vars(), &output.
variables);
105 case ConstraintProto::ConstraintCase::kCircuit:
106 AddIndices(
ct.circuit().literals(), &output.
literals);
108 case ConstraintProto::ConstraintCase::kRoutes:
109 AddIndices(
ct.routes().literals(), &output.
literals);
111 case ConstraintProto::ConstraintCase::kInverse:
112 AddIndices(
ct.inverse().f_direct(), &output.
variables);
113 AddIndices(
ct.inverse().f_inverse(), &output.
variables);
115 case ConstraintProto::ConstraintCase::kReservoir:
116 AddIndices(
ct.reservoir().times(), &output.
variables);
117 AddIndices(
ct.reservoir().actives(), &output.
literals);
119 case ConstraintProto::ConstraintCase::kTable:
122 case ConstraintProto::ConstraintCase::kAutomaton:
123 AddIndices(
ct.automaton().vars(), &output.
variables);
125 case ConstraintProto::ConstraintCase::kInterval:
126 if (
ct.interval().has_start_view()) {
127 AddIndices(
ct.interval().start_view().vars(), &output.
variables);
131 if (
ct.interval().has_size_view()) {
132 AddIndices(
ct.interval().size_view().vars(), &output.
variables);
136 if (
ct.interval().has_end_view()) {
137 AddIndices(
ct.interval().end_view().vars(), &output.
variables);
142 case ConstraintProto::ConstraintCase::kNoOverlap:
144 case ConstraintProto::ConstraintCase::kNoOverlap2D:
146 case ConstraintProto::ConstraintCase::kCumulative:
147 output.
variables.push_back(
ct.cumulative().capacity());
148 AddIndices(
ct.cumulative().demands(), &output.
variables);
150 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
156 #define APPLY_TO_SINGULAR_FIELD(ct_name, field_name) \
158 int temp = ct->mutable_##ct_name()->field_name(); \
160 ct->mutable_##ct_name()->set_##field_name(temp); \
163 #define APPLY_TO_REPEATED_FIELD(ct_name, field_name) \
165 for (int& r : *ct->mutable_##ct_name()->mutable_##field_name()) f(&r); \
169 ConstraintProto*
ct) {
170 for (
int& r : *
ct->mutable_enforcement_literal()) f(&r);
171 switch (
ct->constraint_case()) {
172 case ConstraintProto::ConstraintCase::kBoolOr:
175 case ConstraintProto::ConstraintCase::kBoolAnd:
178 case ConstraintProto::ConstraintCase::kAtMostOne:
181 case ConstraintProto::ConstraintCase::kExactlyOne:
184 case ConstraintProto::ConstraintCase::kBoolXor:
187 case ConstraintProto::ConstraintCase::kIntDiv:
189 case ConstraintProto::ConstraintCase::kIntMod:
191 case ConstraintProto::ConstraintCase::kIntMax:
193 case ConstraintProto::ConstraintCase::kLinMax:
195 case ConstraintProto::ConstraintCase::kIntMin:
197 case ConstraintProto::ConstraintCase::kLinMin:
199 case ConstraintProto::ConstraintCase::kIntProd:
201 case ConstraintProto::ConstraintCase::kLinear:
203 case ConstraintProto::ConstraintCase::kAllDiff:
205 case ConstraintProto::ConstraintCase::kElement:
207 case ConstraintProto::ConstraintCase::kCircuit:
210 case ConstraintProto::ConstraintCase::kRoutes:
213 case ConstraintProto::ConstraintCase::kInverse:
215 case ConstraintProto::ConstraintCase::kReservoir:
218 case ConstraintProto::ConstraintCase::kTable:
220 case ConstraintProto::ConstraintCase::kAutomaton:
222 case ConstraintProto::ConstraintCase::kInterval:
224 case ConstraintProto::ConstraintCase::kNoOverlap:
226 case ConstraintProto::ConstraintCase::kNoOverlap2D:
228 case ConstraintProto::ConstraintCase::kCumulative:
230 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
236 ConstraintProto*
ct) {
237 switch (
ct->constraint_case()) {
238 case ConstraintProto::ConstraintCase::kBoolOr:
240 case ConstraintProto::ConstraintCase::kBoolAnd:
242 case ConstraintProto::ConstraintCase::kAtMostOne:
244 case ConstraintProto::ConstraintCase::kExactlyOne:
246 case ConstraintProto::ConstraintCase::kBoolXor:
248 case ConstraintProto::ConstraintCase::kIntDiv:
252 case ConstraintProto::ConstraintCase::kIntMod:
256 case ConstraintProto::ConstraintCase::kIntMax:
260 case ConstraintProto::ConstraintCase::kLinMax:
262 for (
int i = 0; i <
ct->lin_max().exprs_size(); ++i) {
266 case ConstraintProto::ConstraintCase::kIntMin:
270 case ConstraintProto::ConstraintCase::kLinMin:
272 for (
int i = 0; i <
ct->lin_min().exprs_size(); ++i) {
276 case ConstraintProto::ConstraintCase::kIntProd:
280 case ConstraintProto::ConstraintCase::kLinear:
283 case ConstraintProto::ConstraintCase::kAllDiff:
286 case ConstraintProto::ConstraintCase::kElement:
291 case ConstraintProto::ConstraintCase::kCircuit:
293 case ConstraintProto::ConstraintCase::kRoutes:
295 case ConstraintProto::ConstraintCase::kInverse:
299 case ConstraintProto::ConstraintCase::kReservoir:
302 case ConstraintProto::ConstraintCase::kTable:
305 case ConstraintProto::ConstraintCase::kAutomaton:
308 case ConstraintProto::ConstraintCase::kInterval:
309 if (
ct->interval().has_start_view()) {
314 if (
ct->interval().has_size_view()) {
319 if (
ct->interval().has_end_view()) {
325 case ConstraintProto::ConstraintCase::kNoOverlap:
327 case ConstraintProto::ConstraintCase::kNoOverlap2D:
329 case ConstraintProto::ConstraintCase::kCumulative:
333 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
339 ConstraintProto*
ct) {
340 switch (
ct->constraint_case()) {
341 case ConstraintProto::ConstraintCase::kBoolOr:
343 case ConstraintProto::ConstraintCase::kBoolAnd:
345 case ConstraintProto::ConstraintCase::kAtMostOne:
347 case ConstraintProto::ConstraintCase::kExactlyOne:
349 case ConstraintProto::ConstraintCase::kBoolXor:
351 case ConstraintProto::ConstraintCase::kIntDiv:
353 case ConstraintProto::ConstraintCase::kIntMod:
355 case ConstraintProto::ConstraintCase::kIntMax:
357 case ConstraintProto::ConstraintCase::kLinMax:
359 case ConstraintProto::ConstraintCase::kIntMin:
361 case ConstraintProto::ConstraintCase::kLinMin:
363 case ConstraintProto::ConstraintCase::kIntProd:
365 case ConstraintProto::ConstraintCase::kLinear:
367 case ConstraintProto::ConstraintCase::kAllDiff:
369 case ConstraintProto::ConstraintCase::kElement:
371 case ConstraintProto::ConstraintCase::kCircuit:
373 case ConstraintProto::ConstraintCase::kRoutes:
375 case ConstraintProto::ConstraintCase::kInverse:
377 case ConstraintProto::ConstraintCase::kReservoir:
379 case ConstraintProto::ConstraintCase::kTable:
381 case ConstraintProto::ConstraintCase::kAutomaton:
383 case ConstraintProto::ConstraintCase::kInterval:
385 case ConstraintProto::ConstraintCase::kNoOverlap:
388 case ConstraintProto::ConstraintCase::kNoOverlap2D:
392 case ConstraintProto::ConstraintCase::kCumulative:
395 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
400 #undef APPLY_TO_SINGULAR_FIELD
401 #undef APPLY_TO_REPEATED_FIELD
404 ConstraintProto::ConstraintCase constraint_case) {
405 switch (constraint_case) {
406 case ConstraintProto::ConstraintCase::kBoolOr:
408 case ConstraintProto::ConstraintCase::kBoolAnd:
410 case ConstraintProto::ConstraintCase::kAtMostOne:
412 case ConstraintProto::ConstraintCase::kExactlyOne:
413 return "kExactlyOne";
414 case ConstraintProto::ConstraintCase::kBoolXor:
416 case ConstraintProto::ConstraintCase::kIntDiv:
418 case ConstraintProto::ConstraintCase::kIntMod:
420 case ConstraintProto::ConstraintCase::kIntMax:
422 case ConstraintProto::ConstraintCase::kLinMax:
424 case ConstraintProto::ConstraintCase::kIntMin:
426 case ConstraintProto::ConstraintCase::kLinMin:
428 case ConstraintProto::ConstraintCase::kIntProd:
430 case ConstraintProto::ConstraintCase::kLinear:
432 case ConstraintProto::ConstraintCase::kAllDiff:
434 case ConstraintProto::ConstraintCase::kElement:
436 case ConstraintProto::ConstraintCase::kCircuit:
438 case ConstraintProto::ConstraintCase::kRoutes:
440 case ConstraintProto::ConstraintCase::kInverse:
442 case ConstraintProto::ConstraintCase::kReservoir:
444 case ConstraintProto::ConstraintCase::kTable:
446 case ConstraintProto::ConstraintCase::kAutomaton:
448 case ConstraintProto::ConstraintCase::kInterval:
450 case ConstraintProto::ConstraintCase::kNoOverlap:
452 case ConstraintProto::ConstraintCase::kNoOverlap2D:
453 return "kNoOverlap2D";
454 case ConstraintProto::ConstraintCase::kCumulative:
455 return "kCumulative";
456 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
466 for (
const int lit : references.
literals) {
469 for (
const int lit :
ct.enforcement_literal()) {
477 std::vector<int> used_intervals;
478 switch (
ct.constraint_case()) {
479 case ConstraintProto::ConstraintCase::kBoolOr:
481 case ConstraintProto::ConstraintCase::kBoolAnd:
483 case ConstraintProto::ConstraintCase::kAtMostOne:
485 case ConstraintProto::ConstraintCase::kExactlyOne:
487 case ConstraintProto::ConstraintCase::kBoolXor:
489 case ConstraintProto::ConstraintCase::kIntDiv:
491 case ConstraintProto::ConstraintCase::kIntMod:
493 case ConstraintProto::ConstraintCase::kIntMax:
495 case ConstraintProto::ConstraintCase::kLinMax:
497 case ConstraintProto::ConstraintCase::kIntMin:
499 case ConstraintProto::ConstraintCase::kLinMin:
501 case ConstraintProto::ConstraintCase::kIntProd:
503 case ConstraintProto::ConstraintCase::kLinear:
505 case ConstraintProto::ConstraintCase::kAllDiff:
507 case ConstraintProto::ConstraintCase::kElement:
509 case ConstraintProto::ConstraintCase::kCircuit:
511 case ConstraintProto::ConstraintCase::kRoutes:
513 case ConstraintProto::ConstraintCase::kInverse:
515 case ConstraintProto::ConstraintCase::kReservoir:
517 case ConstraintProto::ConstraintCase::kTable:
519 case ConstraintProto::ConstraintCase::kAutomaton:
521 case ConstraintProto::ConstraintCase::kInterval:
523 case ConstraintProto::ConstraintCase::kNoOverlap:
524 AddIndices(
ct.no_overlap().intervals(), &used_intervals);
526 case ConstraintProto::ConstraintCase::kNoOverlap2D:
527 AddIndices(
ct.no_overlap_2d().x_intervals(), &used_intervals);
528 AddIndices(
ct.no_overlap_2d().y_intervals(), &used_intervals);
530 case ConstraintProto::ConstraintCase::kCumulative:
531 AddIndices(
ct.cumulative().intervals(), &used_intervals);
533 case ConstraintProto::ConstraintCase::CONSTRAINT_NOT_SET:
537 return used_intervals;
542 int64_t objective_value = 0;
543 auto& repeated_field_values =
response.solution().empty()
546 for (
int i = 0; i < objective.vars_size(); ++i) {
547 int64_t coeff = objective.coeffs(i);
548 const int ref = objective.vars(i);
551 objective_value += coeff * repeated_field_values[
var];
553 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)
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