Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
cp_model.proto
Go to the documentation of this file.
1// Copyright 2010-2025 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Proto describing a general Constraint Programming (CP) problem.
15
16syntax = "proto3";
17
18package operations_research.sat;
19
20option csharp_namespace = "Google.OrTools.Sat";
21option go_package = "github.com/google/or-tools/ortools/sat/proto/cpmodel";
22option java_package = "com.google.ortools.sat";
23option java_multiple_files = true;
24option java_outer_classname = "CpModelProtobuf";
25
26// An integer variable.
27//
28// It will be referred to by an int32 corresponding to its index in a
29// CpModelProto variables field.
30//
31// Depending on the context, a reference to a variable whose domain is in [0, 1]
32// can also be seen as a Boolean that will be true if the variable value is 1
33// and false if it is 0. When used in this context, the field name will always
34// contain the word "literal".
35//
36// Negative reference (advanced usage): to simplify the creation of a model and
37// for efficiency reasons, all the "literal" or "variable" fields can also
38// contain a negative index. A negative index i will refer to the negation of
39// the integer variable at index -i -1 or to NOT the literal at the same index.
40//
41// Ex: A variable index 4 will refer to the integer variable model.variables(4)
42// and an index of -5 will refer to the negation of the same variable. A literal
43// index 4 will refer to the logical fact that model.variable(4) == 1 and a
44// literal index of -5 will refer to the logical fact model.variable(4) == 0.
45message IntegerVariableProto {
46 // For debug/logging only. Can be empty.
47 string name = 1;
48
49 // The variable domain given as a sorted list of n disjoint intervals
50 // [min, max] and encoded as [min_0, max_0, ..., min_{n-1}, max_{n-1}].
51 //
52 // The most common example being just [min, max].
53 // If min == max, then this is a constant variable.
54 //
55 // We have:
56 // - domain_size() is always even.
57 // - min == domain.front();
58 // - max == domain.back();
59 // - for all i < n : min_i <= max_i
60 // - for all i < n-1 : max_i + 1 < min_{i+1}.
61 //
62 // Note that we check at validation that a variable domain is small enough so
63 // that we don't run into integer overflow in our algorithms. Because of that,
64 // you cannot just have "unbounded" variable like [0, kint64max] and should
65 // try to specify tighter domains.
66 repeated int64 domain = 2;
67}
68
69// Argument of the constraints of the form OP(literals).
70message BoolArgumentProto {
71 repeated int32 literals = 1;
72}
73
74// Some constraints supports linear expression instead of just using a reference
75// to a variable. This is especially useful during presolve to reduce the model
76// size.
77message LinearExpressionProto {
78 repeated int32 vars = 1;
79 repeated int64 coeffs = 2;
80 int64 offset = 3;
81}
82
83message LinearArgumentProto {
84 LinearExpressionProto target = 1;
85 repeated LinearExpressionProto exprs = 2;
86}
87
88// All affine expressions must take different values.
89message AllDifferentConstraintProto {
90 repeated LinearExpressionProto exprs = 1;
91}
92
93// The linear sum vars[i] * coeffs[i] must fall in the given domain. The domain
94// has the same format as the one in IntegerVariableProto.
95//
96// Note that the validation code currently checks using the domain of the
97// involved variables that the sum can always be computed without integer
98// overflow and throws an error otherwise.
99message LinearConstraintProto {
100 repeated int32 vars = 1;
101 repeated int64 coeffs = 2; // Same size as vars.
102 repeated int64 domain = 3;
103}
104
105// The constraint target = vars[index].
106// This enforces that index takes one of the value in [0, vars_size()).
107message ElementConstraintProto {
108 int32 index = 1; // Legacy field.
109 int32 target = 2; // Legacy field.
110 repeated int32 vars = 3; // Legacy field.
111 // All expressions below must be affine function with at most one variable.
112 LinearExpressionProto linear_index = 4;
113 LinearExpressionProto linear_target = 5;
114 repeated LinearExpressionProto exprs = 6;
115}
116
117// This is not really a constraint. It is there so it can be referred by other
118// constraints using this "interval" concept.
119//
120// IMPORTANT: For now, this constraint do not enforce any relations on the
121// components, and it is up to the client to add in the model:
122// - enforcement => start + size == end.
123// - enforcement => size >= 0 // Only needed if size is not already >= 0.
124//
125// IMPORTANT: For now, we just support affine relation. We could easily
126// create an intermediate variable to support full linear expression, but this
127// isn't done currently.
128message IntervalConstraintProto {
129 LinearExpressionProto start = 4;
130 LinearExpressionProto end = 5;
131 LinearExpressionProto size = 6;
132}
133
134// All the intervals (index of IntervalConstraintProto) must be disjoint. More
135// formally, there must exist a sequence so that for each consecutive intervals,
136// we have end_i <= start_{i+1}. In particular, intervals of size zero do matter
137// for this constraint. This is also known as a disjunctive constraint in
138// scheduling.
139message NoOverlapConstraintProto {
140 repeated int32 intervals = 1;
141}
142
143// The boxes defined by [start_x, end_x) * [start_y, end_y) cannot overlap.
144// Furthermore, one box is optional if at least one of the x or y interval is
145// optional.
146//
147// Note that the case of boxes of size zero is special. The following cases
148// violate the constraint:
149// - a point box inside a box with a non zero area
150// - a line box overlapping a box with a non zero area
151// - one vertical line box crossing an horizontal line box.
152message NoOverlap2DConstraintProto {
153 repeated int32 x_intervals = 1;
154 repeated int32 y_intervals = 2; // Same size as x_intervals.
155}
156
157// The sum of the demands of the intervals at each interval point cannot exceed
158// a capacity. Note that intervals are interpreted as [start, end) and as
159// such intervals like [2,3) and [3,4) do not overlap for the point of view of
160// this constraint. Moreover, intervals of size zero are ignored.
161//
162// All demands must not contain any negative value in their domains. This is
163// checked at validation. Even if there are no intervals, this constraint
164// implicit enforces capacity >= 0. In other words, a negative capacity is
165// considered valid but always infeasible.
166message CumulativeConstraintProto {
167 LinearExpressionProto capacity = 1;
168 repeated int32 intervals = 2;
169 repeated LinearExpressionProto demands = 3; // Same size as intervals.
170}
171
172// Maintain a reservoir level within bounds. The water level starts at 0, and at
173// any time, it must be within [min_level, max_level].
174//
175// If the variable active_literals[i] is true, and if the expression
176// time_exprs[i] is assigned a value t, then the current level changes by
177// level_changes[i] at the time t. Therefore, at any time t:
178//
179// sum(level_changes[i] * active_literals[i] if time_exprs[i] <= t)
180// in [min_level, max_level]
181//
182// Note that min level must be <= 0, and the max level must be >= 0. Please use
183// fixed level_changes to simulate initial state.
184//
185// The array of boolean variables 'actives', if defined, indicates which actions
186// are actually performed. If this array is not defined, then it is assumed that
187// all actions will be performed.
188message ReservoirConstraintProto {
189 int64 min_level = 1;
190 int64 max_level = 2;
191 repeated LinearExpressionProto time_exprs = 3; // affine expressions.
192 // Currently, we only support constant level changes.
193 repeated LinearExpressionProto level_changes = 6; // affine expressions.
194 repeated int32 active_literals = 5;
195 reserved 4;
196}
197
198// The circuit constraint is defined on a graph where the arc presence are
199// controlled by literals. Each arc is given by an index in the
200// tails/heads/literals lists that must have the same size.
201//
202// For now, we ignore node indices with no incident arc. All the other nodes
203// must have exactly one incoming and one outgoing selected arc (i.e. literal at
204// true). All the selected arcs that are not self-loops must form a single
205// circuit. Note that multi-arcs are allowed, but only one of them will be true
206// at the same time. Multi-self loop are disallowed though.
207message CircuitConstraintProto {
208 repeated int32 tails = 3;
209 repeated int32 heads = 4;
210 repeated int32 literals = 5;
211}
212
213// The "VRP" (Vehicle Routing Problem) constraint.
214//
215// The direct graph where arc #i (from tails[i] to head[i]) is present iff
216// literals[i] is true must satisfy this set of properties:
217// - #incoming arcs == 1 except for node 0.
218// - #outgoing arcs == 1 except for node 0.
219// - for node zero, #incoming arcs == #outgoing arcs.
220// - There are no duplicate arcs.
221// - Self-arcs are allowed except for node 0.
222// - There is no cycle in this graph, except through node 0.
223//
224// Note: Currently this constraint expects all the nodes in [0, num_nodes) to
225// have at least one incident arc. The model will be considered invalid if it
226// is not the case. You can add self-arc fixed to one to ignore some nodes if
227// needed.
228//
229// TODO(user): It is probably possible to generalize this constraint to a
230// no-cycle in a general graph, or a no-cycle with sum incoming <= 1 and sum
231// outgoing <= 1 (more efficient implementation). On the other hand, having this
232// specific constraint allow us to add specific "cuts" to a VRP problem.
233message RoutesConstraintProto {
234 repeated int32 tails = 1;
235 repeated int32 heads = 2;
236 repeated int32 literals = 3;
237
238 // DEPRECATED. These fields are no longer used. The solver ignores them.
239 repeated int32 demands = 4;
240 int64 capacity = 5;
241
242 // A set of linear expressions associated with the nodes.
243 message NodeExpressions {
244 // The i-th element is the linear expression associated with the i-th node.
245 // All expressions must be affine expressions (a * var + b).
246 repeated LinearExpressionProto exprs = 1;
247 }
248
249 // Expressions associated with the nodes of the graph, such as the load of the
250 // vehicle arriving at a node, or the time at which a vehicle arrives at a
251 // node. Expressions with the same "dimension" (such as "load" or "time") must
252 // be listed together.
253 // This field is optional. If it is set, the linear constraints of size 1 or 2
254 // between the variables in these expressions will be used to derive cuts for
255 // this constraint. If it is not set, the solver will try to automatically
256 // derive it, from the linear constraints of size 1 or 2 in the model (this
257 // can fail in complex cases).
258 repeated NodeExpressions dimensions = 6;
259}
260
261// The values of the n-tuple formed by the given expression can only be one of
262// the listed n-tuples in values. The n-tuples are encoded in a flattened way:
263// [tuple0_v0, tuple0_v1, ..., tuple0_v{n-1}, tuple1_v0, ...].
264// Expressions must be affine (a * var + b).
265// Corner cases:
266// - If all `vars`, `values` and `exprs` are empty, the constraint is trivially
267// true, irrespective of the value of `negated`.
268// - If `values` is empty but either vars or exprs is not, the constraint is
269// trivially false if `negated` is false, and trivially true if `negated` is
270// true.
271// - If `vars` and `exprs` are empty but `values` is not, the model is invalid.
272message TableConstraintProto {
273 repeated int32 vars = 1; // Legacy field.
274 repeated int64 values = 2;
275 repeated LinearExpressionProto exprs = 4;
276
277 // If true, the meaning is "negated", that is we forbid any of the given
278 // tuple from a feasible assignment.
279 bool negated = 3;
280}
281
282// The two arrays of variable each represent a function, the second is the
283// inverse of the first: f_direct[i] == j <=> f_inverse[j] == i.
284message InverseConstraintProto {
285 repeated int32 f_direct = 1;
286 repeated int32 f_inverse = 2;
287}
288
289// This constraint forces a sequence of expressions to be accepted by an
290// automaton.
291message AutomatonConstraintProto {
292 // A state is identified by a non-negative number. It is preferable to keep
293 // all the states dense in says [0, num_states). The automaton starts at
294 // starting_state and must finish in any of the final states.
295 int64 starting_state = 2;
296 repeated int64 final_states = 3;
297
298 // List of transitions (all 3 vectors have the same size). Both tail and head
299 // are states, label is any variable value. No two outgoing transitions from
300 // the same state can have the same label.
301 repeated int64 transition_tail = 4;
302 repeated int64 transition_head = 5;
303 repeated int64 transition_label = 6;
304
305 // Legacy field.
306 repeated int32 vars = 7;
307 // The sequence of affine expressions (a * var + b). The automaton is ran for
308 // exprs_size() "steps" and the value of exprs[i] corresponds to the
309 // transition label at step i.
310 repeated LinearExpressionProto exprs = 8;
311}
312
313// A list of variables, without any semantics.
314message ListOfVariablesProto {
315 repeated int32 vars = 1;
316}
317
318// Next id: 31
319message ConstraintProto {
320 // For debug/logging only. Can be empty.
321 string name = 1;
322
323 // The constraint will be enforced iff all literals listed here are true. If
324 // this is empty, then the constraint will always be enforced. An enforced
325 // constraint must be satisfied, and an un-enforced one will simply be
326 // ignored.
327 //
328 // This is also called half-reification. To have an equivalence between a
329 // literal and a constraint (full reification), one must add both a constraint
330 // (controlled by a literal l) and its negation (controlled by the negation of
331 // l).
332 //
333 // Important: as of September 2018, only a few constraint support enforcement:
334 // - bool_or, bool_and, linear: fully supported.
335 // - interval: only support a single enforcement literal.
336 // - other: no support (but can be added on a per-demand basis).
337 repeated int32 enforcement_literal = 2;
338
339 // The actual constraint with its arguments.
340 oneof constraint {
341 // The bool_or constraint forces at least one literal to be true.
342 BoolArgumentProto bool_or = 3;
343
344 // The bool_and constraint forces all of the literals to be true.
345 //
346 // This is a "redundant" constraint in the sense that this can easily be
347 // encoded with many bool_or or at_most_one. It is just more space efficient
348 // and handled slightly differently internally.
349 BoolArgumentProto bool_and = 4;
350
351 // The at_most_one constraint enforces that no more than one literal is
352 // true at the same time.
353 //
354 // Note that an at most one constraint of length n could be encoded with n
355 // bool_and constraint with n-1 term on the right hand side. So in a sense,
356 // this constraint contribute directly to the "implication-graph" or the
357 // 2-SAT part of the model.
358 //
359 // This constraint does not support enforcement_literal. Just use a linear
360 // constraint if you need to enforce it. You also do not need to use it
361 // directly, we will extract it from the model in most situations.
362 BoolArgumentProto at_most_one = 26;
363
364 // The exactly_one constraint force exactly one literal to true and no more.
365 //
366 // Anytime a bool_or (it could have been called at_least_one) is included
367 // into an at_most_one, then the bool_or is actually an exactly one
368 // constraint, and the extra literal in the at_most_one can be set to false.
369 // So in this sense, this constraint is not really needed. it is just here
370 // for a better description of the problem structure and to facilitate some
371 // algorithm.
372 //
373 // This constraint does not support enforcement_literal. Just use a linear
374 // constraint if you need to enforce it. You also do not need to use it
375 // directly, we will extract it from the model in most situations.
376 BoolArgumentProto exactly_one = 29;
377
378 // The bool_xor constraint forces an odd number of the literals to be true.
379 BoolArgumentProto bool_xor = 5;
380
381 // The int_div constraint forces the target to equal exprs[0] / exprs[1].
382 // The division is "rounded" towards zero, so we can have for instance
383 // (2 = 12 / 5) or (-3 = -10 / 3). If you only want exact integer division,
384 // then you should use instead of t = a / b, the int_prod constraint
385 // a = b * t.
386 //
387 // If 0 belongs to the domain of exprs[1], then the model is deemed invalid.
388 LinearArgumentProto int_div = 7;
389
390 // The int_mod constraint forces the target to equal exprs[0] % exprs[1].
391 // The domain of exprs[1] must be strictly positive. The sign of the target
392 // is the same as the sign of exprs[0].
393 LinearArgumentProto int_mod = 8;
394
395 // The int_prod constraint forces the target to equal the product of all
396 // variables. By convention, because we can just remove term equal to one,
397 // the empty product forces the target to be one.
398 //
399 // Note that the solver checks for potential integer overflow. So the
400 // product of the maximum absolute value of all the terms (using the initial
401 // domain) should fit on an int64. Otherwise the model will be declared
402 // invalid.
403 LinearArgumentProto int_prod = 11;
404
405 // The lin_max constraint forces the target to equal the maximum of all
406 // linear expressions.
407 // Note that this can model a minimum simply by negating all expressions.
408 LinearArgumentProto lin_max = 27;
409
410 // The linear constraint enforces a linear inequality among the variables,
411 // such as 0 <= x + 2y <= 10.
412 LinearConstraintProto linear = 12;
413
414 // The all_diff constraint forces all variables to take different values.
415 AllDifferentConstraintProto all_diff = 13;
416
417 // The element constraint forces the variable with the given index
418 // to be equal to the target.
419 ElementConstraintProto element = 14;
420
421 // The circuit constraint takes a graph and forces the arcs present
422 // (with arc presence indicated by a literal) to form a unique cycle.
423 CircuitConstraintProto circuit = 15;
424
425 // The routes constraint implements the vehicle routing problem.
426 RoutesConstraintProto routes = 23;
427
428 // The table constraint enforces what values a tuple of variables may
429 // take.
430 TableConstraintProto table = 16;
431
432 // The automaton constraint forces a sequence of variables to be accepted
433 // by an automaton.
434 AutomatonConstraintProto automaton = 17;
435
436 // The inverse constraint forces two arrays to be inverses of each other:
437 // the values of one are the indices of the other, and vice versa.
438 InverseConstraintProto inverse = 18;
439
440 // The reservoir constraint forces the sum of a set of active demands
441 // to always be between a specified minimum and maximum value during
442 // specific times.
443 ReservoirConstraintProto reservoir = 24;
444
445 // Constraints on intervals.
446 //
447 // The first constraint defines what an "interval" is and the other
448 // constraints use references to it. All the intervals that have an
449 // enforcement_literal set to false are ignored by these constraints.
450 //
451 // TODO(user): Explain what happen for intervals of size zero. Some
452 // constraints ignore them; others do take them into account.
453
454 // The interval constraint takes a start, end, and size, and forces
455 // start + size == end.
456 IntervalConstraintProto interval = 19;
457
458 // The no_overlap constraint prevents a set of intervals from
459 // overlapping; in scheduling, this is called a disjunctive
460 // constraint.
461 NoOverlapConstraintProto no_overlap = 20;
462
463 // The no_overlap_2d constraint prevents a set of boxes from overlapping.
464 NoOverlap2DConstraintProto no_overlap_2d = 21;
465
466 // The cumulative constraint ensures that for any integer point, the sum
467 // of the demands of the intervals containing that point does not exceed
468 // the capacity.
469 CumulativeConstraintProto cumulative = 22;
470
471 // This constraint is not meant to be used and will be rejected by the
472 // solver. It is meant to mark variable when testing the presolve code.
473 ListOfVariablesProto dummy_constraint = 30;
474 }
475}
476
477// Optimization objective.
478message CpObjectiveProto {
479 // The linear terms of the objective to minimize.
480 // For a maximization problem, one can negate all coefficients in the
481 // objective and set scaling_factor to -1.
482 repeated int32 vars = 1;
483 repeated int64 coeffs = 4;
484
485 // The displayed objective is always:
486 // scaling_factor * (sum(coefficients[i] * objective_vars[i]) + offset).
487 // This is needed to have a consistent objective after presolve or when
488 // scaling a double problem to express it with integers.
489 //
490 // Note that if scaling_factor is zero, then it is assumed to be 1, so that by
491 // default these fields have no effect.
492 double offset = 2;
493 double scaling_factor = 3;
494
495 // If non-empty, only look for an objective value in the given domain.
496 // Note that this does not depend on the offset or scaling factor, it is a
497 // domain on the sum of the objective terms only.
498 repeated int64 domain = 5;
499
500 // Internal field. Do not set. When we scale a FloatObjectiveProto to a
501 // integer version, we set this to true if the scaling was exact (i.e. all
502 // original coeff were integer for instance).
503 //
504 // TODO(user): Put the error bounds we computed instead?
505 bool scaling_was_exact = 6;
506
507 // Internal fields to recover a bound on the original integer objective from
508 // the presolved one. Basically, initially the integer objective fit on an
509 // int64 and is in [Initial_lb, Initial_ub]. During presolve, we might change
510 // the linear expression to have a new domain [Presolved_lb, Presolved_ub]
511 // that will also always fit on an int64.
512 //
513 // The two domain will always be linked with an affine transformation between
514 // the two of the form:
515 // old = (new + before_offset) * integer_scaling_factor + after_offset.
516 // Note that we use both offsets to always be able to do the computation while
517 // staying in the int64 domain. In particular, the after_offset will always
518 // be in (-integer_scaling_factor, integer_scaling_factor).
519 int64 integer_before_offset = 7;
520 int64 integer_after_offset = 9;
521 int64 integer_scaling_factor = 8;
522}
523
524// A linear floating point objective: sum coeffs[i] * vars[i] + offset.
525// Note that the variable can only still take integer value.
526message FloatObjectiveProto {
527 repeated int32 vars = 1;
528 repeated double coeffs = 2;
529 double offset = 3;
530
531 // The optimization direction. The default is to minimize
532 bool maximize = 4;
533}
534
535// Define the strategy to follow when the solver needs to take a new decision.
536// Note that this strategy is only defined on a subset of variables.
537message DecisionStrategyProto {
538 // The variables to be considered for the next decision. The order matter and
539 // is always used as a tie-breaker after the variable selection strategy
540 // criteria defined below.
541 repeated int32 variables = 1;
542
543 // If this is set, then the variables field must be empty.
544 // We currently only support affine expression.
545 //
546 // Note that this is needed so that if a variable has an affine
547 // representative, we can properly transform a DecisionStrategyProto through
548 // presolve.
549 repeated LinearExpressionProto exprs = 5;
550
551 // The order in which the variables (resp. affine expression) above should be
552 // considered. Note that only variables that are not already fixed are
553 // considered.
554 //
555 // TODO(user): extend as needed.
556 enum VariableSelectionStrategy {
557 CHOOSE_FIRST = 0;
558 CHOOSE_LOWEST_MIN = 1;
559 CHOOSE_HIGHEST_MAX = 2;
560 CHOOSE_MIN_DOMAIN_SIZE = 3;
561 CHOOSE_MAX_DOMAIN_SIZE = 4;
562 }
563 VariableSelectionStrategy variable_selection_strategy = 2;
564
565 // Once a variable (resp. affine expression) has been chosen, this enum
566 // describe what decision is taken on its domain.
567 //
568 // TODO(user): extend as needed.
569 enum DomainReductionStrategy {
570 SELECT_MIN_VALUE = 0;
571 SELECT_MAX_VALUE = 1;
572 SELECT_LOWER_HALF = 2;
573 SELECT_UPPER_HALF = 3;
574 SELECT_MEDIAN_VALUE = 4;
575 SELECT_RANDOM_HALF = 5;
576 }
577 DomainReductionStrategy domain_reduction_strategy = 3;
578}
579
580// This message encodes a partial (or full) assignment of the variables of a
581// CpModelProto. The variable indices should be unique and valid variable
582// indices.
583message PartialVariableAssignment {
584 repeated int32 vars = 1;
585 repeated int64 values = 2;
586}
587
588// A permutation of integers encoded as a list of cycles, hence the "sparse"
589// format. The image of an element cycle[i] is cycle[(i + 1) % cycle_length].
590message SparsePermutationProto {
591 // Each cycle is listed one after the other in the support field.
592 // The size of each cycle is given (in order) in the cycle_sizes field.
593 repeated int32 support = 1;
594 repeated int32 cycle_sizes = 2;
595}
596
597// A dense matrix of numbers encoded in a flat way, row by row.
598// That is matrix[i][j] = entries[i * num_cols + j];
599message DenseMatrixProto {
600 int32 num_rows = 1;
601 int32 num_cols = 2;
602 repeated int32 entries = 3;
603}
604
605// EXPERIMENTAL. For now, this is meant to be used by the solver and not filled
606// by clients.
607//
608// Hold symmetry information about the set of feasible solutions. If we permute
609// the variable values of any feasible solution using one of the permutation
610// described here, we should always get another feasible solution.
611//
612// We usually also enforce that the objective of the new solution is the same.
613//
614// The group of permutations encoded here is usually computed from the encoding
615// of the model, so it is not meant to be a complete representation of the
616// feasible solution symmetries, just a valid subgroup.
617message SymmetryProto {
618 // A list of variable indices permutations that leave the feasible space of
619 // solution invariant. Usually, we only encode a set of generators of the
620 // group.
621 repeated SparsePermutationProto permutations = 1;
622
623 // An orbitope is a special symmetry structure of the solution space. If the
624 // variable indices are arranged in a matrix (with no duplicates), then any
625 // permutation of the columns will be a valid permutation of the feasible
626 // space.
627 //
628 // This arise quite often. The typical example is a graph coloring problem
629 // where for each node i, you have j booleans to indicate its color. If the
630 // variables color_of_i_is_j are arranged in a matrix[i][j], then any columns
631 // permutations leave the problem invariant.
632 repeated DenseMatrixProto orbitopes = 2;
633}
634
635// A constraint programming problem.
636message CpModelProto {
637 // For debug/logging only. Can be empty.
638 string name = 1;
639
640 // The associated Protos should be referred by their index in these fields.
641 repeated IntegerVariableProto variables = 2;
642 repeated ConstraintProto constraints = 3;
643
644 // The objective to minimize. Can be empty for pure decision problems.
645 CpObjectiveProto objective = 4;
646
647 // Advanced usage.
648 // It is invalid to have both an objective and a floating point objective.
649 //
650 // The objective of the model, in floating point format. The solver will
651 // automatically scale this to integer during expansion and thus convert it to
652 // a normal CpObjectiveProto. See the mip* parameters to control how this is
653 // scaled. In most situation the precision will be good enough, but you can
654 // see the logs to see what are the precision guaranteed when this is
655 // converted to a fixed point representation.
656 //
657 // Note that even if the precision is bad, the returned objective_value and
658 // best_objective_bound will be computed correctly. So at the end of the solve
659 // you can check the gap if you only want precise optimal.
660 FloatObjectiveProto floating_point_objective = 9;
661
662 // Defines the strategy that the solver should follow when the
663 // search_branching parameter is set to FIXED_SEARCH. Note that this strategy
664 // is also used as a heuristic when we are not in fixed search.
665 //
666 // Advanced Usage: if not all variables appears and the parameter
667 // "instantiate_all_variables" is set to false, then the solver will not try
668 // to instantiate the variables that do not appear. Thus, at the end of the
669 // search, not all variables may be fixed. Currently, we will set them to
670 // their lower bound in the solution.
671 repeated DecisionStrategyProto search_strategy = 5;
672
673 // Solution hint.
674 //
675 // If a feasible or almost-feasible solution to the problem is already known,
676 // it may be helpful to pass it to the solver so that it can be used. The
677 // solver will try to use this information to create its initial feasible
678 // solution.
679 //
680 // Note that it may not always be faster to give a hint like this to the
681 // solver. There is also no guarantee that the solver will use this hint or
682 // try to return a solution "close" to this assignment in case of multiple
683 // optimal solutions.
684 PartialVariableAssignment solution_hint = 6;
685
686 // A list of literals. The model will be solved assuming all these literals
687 // are true. Compared to just fixing the domain of these literals, using this
688 // mechanism is slower but allows in case the model is INFEASIBLE to get a
689 // potentially small subset of them that can be used to explain the
690 // infeasibility.
691 //
692 // Think (IIS), except when you are only concerned by the provided
693 // assumptions. This is powerful as it allows to group a set of logically
694 // related constraint under only one enforcement literal which can potentially
695 // give you a good and interpretable explanation for infeasiblity.
696 //
697 // Such infeasibility explanation will be available in the
698 // sufficient_assumptions_for_infeasibility response field.
699 repeated int32 assumptions = 7;
700
701 // For now, this is not meant to be filled by a client writing a model, but
702 // by our preprocessing step.
703 //
704 // Information about the symmetries of the feasible solution space.
705 // These usually leaves the objective invariant.
706 SymmetryProto symmetry = 8;
707}
708
709// The status returned by a solver trying to solve a CpModelProto.
710enum CpSolverStatus {
711 // The status of the model is still unknown. A search limit has been reached
712 // before any of the statuses below could be determined.
713 UNKNOWN = 0;
714
715 // The given CpModelProto didn't pass the validation step. You can get a
716 // detailed error by calling ValidateCpModel(model_proto).
717 MODEL_INVALID = 1;
718
719 // A feasible solution has been found. But the search was stopped before we
720 // could prove optimality or before we enumerated all solutions of a
721 // feasibility problem (if asked).
722 FEASIBLE = 2;
723
724 // The problem has been proven infeasible.
725 INFEASIBLE = 3;
726
727 // An optimal feasible solution has been found.
728 //
729 // More generally, this status represent a success. So we also return OPTIMAL
730 // if we find a solution for a pure feasibility problem or if a gap limit has
731 // been specified and we return a solution within this limit. In the case
732 // where we need to return all the feasible solution, this status will only be
733 // returned if we enumerated all of them; If we stopped before, we will return
734 // FEASIBLE.
735 OPTIMAL = 4;
736}
737
738// Just a message used to store dense solution.
739// This is used by the additional_solutions field.
740message CpSolverSolution {
741 repeated int64 values = 1;
742}
743
744// The response returned by a solver trying to solve a CpModelProto.
745//
746// Next id: 32
747message CpSolverResponse {
748 // The status of the solve.
749 CpSolverStatus status = 1;
750
751 // A feasible solution to the given problem. Depending on the returned status
752 // it may be optimal or just feasible. This is in one-to-one correspondence
753 // with a CpModelProto::variables repeated field and list the values of all
754 // the variables.
755 repeated int64 solution = 2;
756
757 // Only make sense for an optimization problem. The objective value of the
758 // returned solution if it is non-empty. If there is no solution, then for a
759 // minimization problem, this will be an upper-bound of the objective of any
760 // feasible solution, and a lower-bound for a maximization problem.
761 double objective_value = 3;
762
763 // Only make sense for an optimization problem. A proven lower-bound on the
764 // objective for a minimization problem, or a proven upper-bound for a
765 // maximization problem.
766 double best_objective_bound = 4;
767
768 // If the parameter fill_additional_solutions_in_response is set, then we
769 // copy all the solutions from our internal solution pool here.
770 //
771 // Note that the one returned in the solution field will likely appear here
772 // too. Do not rely on the solutions order as it depends on our internal
773 // representation (after postsolve).
774 repeated CpSolverSolution additional_solutions = 27;
775
776 // Advanced usage.
777 //
778 // If the option fill_tightened_domains_in_response is set, then this field
779 // will be a copy of the CpModelProto.variables where each domain has been
780 // reduced using the information the solver was able to derive. Note that this
781 // is only filled with the info derived during a normal search and we do not
782 // have any dedicated algorithm to improve it.
783 //
784 // Warning: if you didn't set keep_all_feasible_solutions_in_presolve, then
785 // these domains might exclude valid feasible solution. Otherwise for a
786 // feasibility problem, all feasible solution should be there.
787 //
788 // Warning: For an optimization problem, these will correspond to valid bounds
789 // for the problem of finding an improving solution to the best one found so
790 // far. It might be better to solve a feasibility version if one just want to
791 // explore the feasible region.
792 repeated IntegerVariableProto tightened_variables = 21;
793
794 // A subset of the model "assumptions" field. This will only be filled if the
795 // status is INFEASIBLE. This subset of assumption will be enough to still get
796 // an infeasible problem.
797 //
798 // This is related to what is called the irreducible inconsistent subsystem or
799 // IIS. Except one is only concerned by the provided assumptions. There is
800 // also no guarantee that we return an irreducible (aka minimal subset).
801 // However, this is based on SAT explanation and there is a good chance it is
802 // not too large.
803 //
804 // If you really want a minimal subset, a possible way to get one is by
805 // changing your model to minimize the number of assumptions at false, but
806 // this is likely an harder problem to solve.
807 //
808 // Important: Currently, this is minimized only in single-thread and if the
809 // problem is not an optimization problem, otherwise, it will always include
810 // all the assumptions.
811 //
812 // TODO(user): Allows for returning multiple core at once.
813 repeated int32 sufficient_assumptions_for_infeasibility = 23;
814
815 // Contains the integer objective optimized internally. This is only filled if
816 // the problem had a floating point objective, and on the final response, not
817 // the ones given to callbacks.
818 CpObjectiveProto integer_objective = 28;
819
820 // Advanced usage.
821 //
822 // A lower bound on the integer expression of the objective. This is either a
823 // bound on the expression in the returned integer_objective or on the integer
824 // expression of the original objective if the problem already has an integer
825 // objective.
826 //
827 // TODO(user): This should be renamed integer_objective_lower_bound.
828 int64 inner_objective_lower_bound = 29;
829
830 // Some statistics about the solve.
831 //
832 // Important: in multithread, this correspond the statistics of the first
833 // subsolver. Which is usually the one with the user defined parameters. Or
834 // the default-search if none are specified.
835 int64 num_integers = 30;
836 int64 num_booleans = 10;
837 int64 num_fixed_booleans = 31;
838 int64 num_conflicts = 11;
839 int64 num_branches = 12;
840 int64 num_binary_propagations = 13;
841 int64 num_integer_propagations = 14;
842 int64 num_restarts = 24;
843 int64 num_lp_iterations = 25;
844
845 // The time counted from the beginning of the Solve() call.
846 double wall_time = 15;
847 double user_time = 16;
848 double deterministic_time = 17;
849
850 // The integral of log(1 + absolute_objective_gap) over time.
851 double gap_integral = 22;
852
853 // Additional information about how the solution was found. It also stores
854 // model or parameters errors that caused the model to be invalid.
855 string solution_info = 20;
856
857 // The solve log will be filled if the parameter log_to_response is set to
858 // true.
859 string solve_log = 26;
860}