1// Copyright 2010-2021 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// Linear Programming Protocol Buffers.
15//
16// The protocol buffers below make it possible to store and transfer the
17// representation of Linear and Mixed-Integer Programs.
18//
19// A Linear Program (LP) is a mathematical optimization model with a linear
20// objective function, and linear equality and inequality constraints.
21// The goal is to achieve the best outcome (such as maximum profit or lowest
22// cost) by modeling the real-world problem at hand using linear functions.
23// In a Mixed Integer Program (MIP), some variables may also be constrained to
24// take integer values.
25//
26// Check ./linear_solver.h and Wikipedia for more detail:
27//   http://en.wikipedia.org/wiki/Linear_programming
28//
29
30syntax = "proto2";
31
32option java_package = "com.google.ortools.linearsolver";
33option java_multiple_files = true;
34
35import "ortools/util/optional_boolean.proto";
36
37package operations_research;
38
39// A variable is always constrained in the form:
40//    lower_bound <= x <= upper_bound
41// where lower_bound and upper_bound:
42// - Can form a singleton: x = constant = lower_bound = upper_bound.
43// - Can form a finite interval: lower_bound <= x <= upper_bound. (x is boxed.)
44// - Can form a semi-infinite interval.
45//     - lower_bound = -infinity: x <= upper_bound.
46//     - upper_bound = +infinity: x >= lower_bound.
47// - Can form the infinite interval: lower_bound = -infinity and
48//   upper_bound = +infinity, x is free.
49// MPVariableProto furthermore stores:
50//  - The coefficient of the variable in the objective.
51//  - Whether the variable is integer.
52message MPVariableProto {
53  // lower_bound must be <= upper_bound.
54  optional double lower_bound = 1 [default = -inf];
55  optional double upper_bound = 2 [default = inf];
56
57  // The coefficient of the variable in the objective. Must be finite.
58  optional double objective_coefficient = 3 [default = 0.0];
59
60  // True if the variable is constrained to be integer.
61  // Ignored if MPModelProto::solver_type is *LINEAR_PROGRAMMING*.
62  optional bool is_integer = 4 [default = false];
63
64  // The name of the variable.
65  optional string name = 5 [default = ""];
66
67  optional int32 branching_priority = 6 [default = 0];
68}
69
70// A linear constraint is always of the form:
71// lower_bound <= sum of linear term elements <= upper_bound,
72// where lower_bound and upper_bound:
73// - Can form a singleton: lower_bound == upper_bound. The constraint is an
74//   equation.
75// - Can form a finite interval [lower_bound, upper_bound]. The constraint is
76//   both lower- and upper-bounded, i.e. "boxed".
77// - Can form a semi-infinite interval. lower_bound = -infinity: the constraint
78//   is upper-bounded. upper_bound = +infinity: the constraint is lower-bounded.
79// - Can form the infinite interval: lower_bound = -infinity and
80//   upper_bound = +infinity. The constraint is free.
81message MPConstraintProto {
82  // var_index[i] is the variable index (w.r.t. to "variable" field of
83  // MPModelProto) of the i-th linear term involved in this constraint, and
84  // coefficient[i] is its coefficient. Only the terms with non-zero
85  // coefficients need to appear. var_index may not contain duplicates.
86  repeated int32 var_index = 6 [packed = true];
87  repeated double coefficient = 7 [packed = true];  // Must be finite.
88
89  // lower_bound must be <= upper_bound.
90  optional double lower_bound = 2 [default = -inf];
91  optional double upper_bound = 3 [default = inf];
92
93  // The name of the constraint.
94  optional string name = 4 [default = ""];
95
96  // [Advanced usage: do not use this if you don't know what you're doing.]
97  // A lazy constraint is handled differently by the core solving engine, but
98  // it does not change the result. It may or may not impact the performance.
99  // For more info see: http://tinyurl.com/lazy-constraints.
100  optional bool is_lazy = 5 [default = false];
101}
102
103// General constraints. See each individual proto type for more information.
104message MPGeneralConstraintProto {
105  // The name of the constraint.
106  optional string name = 1 [default = ""];
107
108  oneof general_constraint {
109    MPIndicatorConstraint indicator_constraint = 2;
110    MPSosConstraint sos_constraint = 3;
111    MPQuadraticConstraint quadratic_constraint = 4;
112    MPAbsConstraint abs_constraint = 5;
113    // All variables in "and" constraints must be Boolean.
114    // resultant_var = and(var_1, var_2... var_n)
115    MPArrayConstraint and_constraint = 6;
116    // All variables in "or" constraints must be Boolean.
117    // resultant_var = or(var_1, var_2... var_n)
118    MPArrayConstraint or_constraint = 7;
119    // resultant_var = min(var_1, var_2, ..., constant)
120    MPArrayWithConstantConstraint min_constraint = 8;
121    // resultant_var = max(var_1, var_2, ..., constant)
122    MPArrayWithConstantConstraint max_constraint = 9;
123  }
124}
125
126// Indicator constraints encode the activation or deactivation of linear
127// constraints given the value of one Boolean variable in the model. For
128// example:
129//     y = 0 => 2 * x1 + 3 * x2 >= 42
130// The 2 * x1 + 3 * x2 >= 42 constraint is only active if the variable y is
131// equal to 0.
132// As of 2019/04, only SCIP, CP-SAT and Gurobi support this constraint type.
133message MPIndicatorConstraint {
134  // Variable index (w.r.t. the "variable" field of MPModelProto) of the Boolean
135  // variable used as indicator.
136  optional int32 var_index = 1;
137
138  // Value the above variable should take. Must be 0 or 1.
139  optional int32 var_value = 2;
140
141  // The constraint activated by the indicator variable.
142  optional MPConstraintProto constraint = 3;
143}
144
145// Special Ordered Set (SOS) constraints of type 1 or 2.
146// See https://en.wikipedia.org/wiki/Special_ordered_set
147// As of 2019/04, only SCIP and Gurobi support this constraint type.
148message MPSosConstraint {
149  enum Type {
150    // At most one variable in `var_index` must be non-zero.
151    SOS1_DEFAULT = 0;
152    // At most two consecutive variables from `var_index` can be non-zero (i.e.
153    // for some i, var_index[i] and var_index[i+1]). See
154    // https://en.wikipedia.org/wiki/Special_ordered_set#Types_of_SOS
155    SOS2 = 1;
156  }
157  optional Type type = 1 [default = SOS1_DEFAULT];
158
159  // Variable index (w.r.t. the "variable" field of MPModelProto) of the
160  // variables in the SOS.
161  repeated int32 var_index = 2;
162
163  // Optional: SOS weights. If non-empty, must be of the same size as
164  // "var_index", and strictly increasing. If empty and required by the
165  // underlying solver, the 1..n sequence will be given as weights.
166  // SUBTLE: The weights can help the solver make branch-and-bound decisions
167  // that fit the underlying optimization model: after each LP relaxation, it
168  // will compute the "average weight" of the SOS variables, weighted by value
169  // (this is confusing: here we're using the values as weights), and the binary
170  // branch decision will be: is the non-zero variable above or below that?
171  // (weights are strictly monotonous, so the "cutoff" average weight
172  // corresponds to a "cutoff" index in the var_index sequence).
173  repeated double weight = 3;
174}
175
176// Quadratic constraints of the form lb <= sum a_i x_i + sum b_ij x_i x_j <= ub,
177// where a, b, lb and ub are constants, and x are the model's variables.
178// Quadratic matrices that are Positive Semi-Definite, Second-Order Cones or
179// rotated Second-Order Cones are always accepted. Other forms may or may not be
180// accepted depending on the underlying solver used.
181// See https://scip.zib.de/doc/html/cons__quadratic_8h.php and
182// https://www.gurobi.com/documentation/9.0/refman/constraints.html#subsubsection:QuadraticConstraints
183message MPQuadraticConstraint {
184  // Sparse representation of linear terms in the quadratic constraint, where
185  // term i is var_index[i] * coefficient[i].
186  // `var_index` are variable indices w.r.t the "variable" field in
187  // MPModelProto, and should be unique.
188  repeated int32 var_index = 1;
189  repeated double coefficient = 2;  // Must be finite.
190
191  // Sparse representation of quadratic terms in the quadratic constraint, where
192  // term i is qvar1_index[i] * qvar2_index[i] * qcoefficient[i].
193  // `qvar1_index` and `qvar2_index` are variable indices w.r.t the "variable"
194  // field in MPModelProto.
195  // `qvar1_index`, `qvar2_index` and `coefficients` must have the same size.
196  // If the same unordered pair (qvar1_index, qvar2_index) appears several
197  // times, the sum of all of the associated coefficients will be applied.
198  repeated int32 qvar1_index = 3;
199  repeated int32 qvar2_index = 4;
200  repeated double qcoefficient = 5;  // Must be finite.
201
202  // lower_bound must be <= upper_bound.
203  optional double lower_bound = 6 [default = -inf];
204  optional double upper_bound = 7 [default = inf];
205}
206
207// Sets a variable's value to the absolute value of another variable.
208message MPAbsConstraint {
209  // Variable indices are relative to the "variable" field in MPModelProto.
210  // resultant_var = abs(var)
211  optional int32 var_index = 1;
212  optional int32 resultant_var_index = 2;
213}
214
215// Sets a variable's value equal to a function on a set of variables.
216message MPArrayConstraint {
217  // Variable indices are relative to the "variable" field in MPModelProto.
218  repeated int32 var_index = 1;
219  optional int32 resultant_var_index = 2;
220}
221
222// Sets a variable's value equal to a function on a set of variables and,
223// optionally, a constant.
224message MPArrayWithConstantConstraint {
225  // Variable indices are relative to the "variable" field in MPModelProto.
226  // resultant_var = f(var_1, var_2, ..., constant)
227  repeated int32 var_index = 1;
228  optional double constant = 2;
229  optional int32 resultant_var_index = 3;
230}
231
232// Quadratic part of a model's objective. Added with other objectives (such as
233// linear), this creates the model's objective function to be optimized.
234// Note: the linear part of the objective currently needs to be specified in the
235// MPVariableProto.objective_coefficient fields. If you'd rather have a
236// dedicated linear array here, talk to or-core-team@
237message MPQuadraticObjective {
238  // Sparse representation of quadratic terms in the objective function, where
239  // term i is qvar1_index[i] * qvar2_index[i] * coefficient[i].
240  // `qvar1_index` and `qvar2_index` are variable indices w.r.t the "variable"
241  // field in MPModelProto.
242  // `qvar1_index`, `qvar2_index` and `coefficients` must have the same size.
243  // If the same unordered pair (qvar1_index, qvar2_index) appears several
244  // times, the sum of all of the associated coefficients will be applied.
245  repeated int32 qvar1_index = 1;
246  repeated int32 qvar2_index = 2;
247  repeated double coefficient = 3;  // Must be finite.
248}
249
250// This message encodes a partial (or full) assignment of the variables of a
251// MPModelProto problem. The indices in var_index should be unique and valid
252// variable indices of the associated problem.
253message PartialVariableAssignment {
254  repeated int32 var_index = 1 [packed = true];
255  repeated double var_value = 2 [packed = true];
256}
257
258// MPModelProto contains all the information for a Linear Programming model.
259message MPModelProto {
260  // All the variables appearing in the model.
261  repeated MPVariableProto variable = 3;
262
263  // All the constraints appearing in the model.
264  repeated MPConstraintProto constraint = 4;
265
266  // All the general constraints appearing in the model. Note that not all
267  // solvers support all types of general constraints.
268  repeated MPGeneralConstraintProto general_constraint = 7;
269
270  // True if the problem is a maximization problem. Minimize by default.
271  optional bool maximize = 1 [default = false];
272
273  // Offset for the objective function. Must be finite.
274  optional double objective_offset = 2 [default = 0.0];
275
276  // Optionally, a quadratic objective.
277  // As of 2019/06, only SCIP and Gurobi support quadratic objectives.
278  optional MPQuadraticObjective quadratic_objective = 8;
279
280  // Name of the model.
281  optional string name = 5 [default = ""];
282
283  // Solution hint.
284  //
285  // If a feasible or almost-feasible solution to the problem is already known,
286  // it may be helpful to pass it to the solver so that it can be used. A solver
287  // that supports this feature will try to use this information to create its
288  // initial feasible solution.
289  //
290  // Note that it may not always be faster to give a hint like this to the
291  // solver. There is also no guarantee that the solver will use this hint or
292  // try to return a solution "close" to this assignment in case of multiple
293  // optimal solutions.
294  optional PartialVariableAssignment solution_hint = 6;
295}
296
297// To support 'unspecified' double value in proto3, the simplest is to wrap
298// any double value in a nested message (has_XXX works for message fields).
299message OptionalDouble {
300  optional double value = 1;
301}
302
303// MPSolverCommonParameters holds advanced usage parameters that apply to any of
304// the solvers we support.
305// All of the fields in this proto can have a value of unspecified. In this
306// case each inner solver will use their own safe defaults.
307// Some values won't be supported by some solvers. The behavior in that case is
308// not defined yet.
309message MPSolverCommonParameters {
310  // The solver stops if the relative MIP gap reaches this value or below.
311  // The relative MIP gap is an upper bound of the relative distance to the
312  // optimum, and it is defined as:
313  //
314  //   abs(best_bound - incumbent) / abs(incumbent) [Gurobi]
315  //   abs(best_bound - incumbent) / min(abs(best_bound), abs(incumbent)) [SCIP]
316  //
317  // where "incumbent" is the objective value of the best solution found so far
318  // (i.e., lowest when minimizing, highest when maximizing), and "best_bound"
319  // is the tightest bound of the objective determined so far (i.e., highest
320  // when minimizing, and lowest when maximizing). The MIP Gap is sensitive to
321  // objective offset. If the denominator is 0 the MIP Gap is INFINITY for SCIP
322  // and Gurobi. Of note, "incumbent" and "best bound" are called "primal bound"
323  // and "dual bound" in SCIP, respectively.
324  // Ask or-core-team@ for other solvers.
325  optional OptionalDouble relative_mip_gap = 1;
326
327  // Tolerance for primal feasibility of basic solutions: this is the maximum
328  // allowed error in constraint satisfiability.
329  // For SCIP this includes integrality constraints. For Gurobi it does not, you
330  // need to set the custom parameter IntFeasTol.
331  optional OptionalDouble primal_tolerance = 2;
332
333  // Tolerance for dual feasibility.
334  // For SCIP and Gurobi this is the feasibility tolerance for reduced costs in
335  // LP solution: reduced costs must all be smaller than this value in the
336  // improving direction in order for a model to be declared optimal.
337  // Not supported for other solvers.
338  optional OptionalDouble dual_tolerance = 3;
339
340  enum LPAlgorithmValues {
341    LP_ALGO_UNSPECIFIED = 0;
342    LP_ALGO_DUAL = 1;     // Dual simplex.
343    LP_ALGO_PRIMAL = 2;   // Primal simplex.
344    LP_ALGO_BARRIER = 3;  // Barrier algorithm.
345  }
346
347  // Algorithm to solve linear programs.
348  // Ask or-core-team@ if you want to know what this does exactly.
349  optional LPAlgorithmValues lp_algorithm = 4 [default = LP_ALGO_UNSPECIFIED];
350
351  // Gurobi and SCIP enable presolve by default.
352  // Ask or-core-team@ for other solvers.
353  optional OptionalBoolean presolve = 5 [default = BOOL_UNSPECIFIED];
354
355  // Enable automatic scaling of matrix coefficients and objective. Available
356  // for Gurobi and GLOP.
357  // Ask or-core-team@ if you want more details.
358  optional OptionalBoolean scaling = 7 [default = BOOL_UNSPECIFIED];
359}
360
361// Encodes a full MPModelProto by way of referencing to a "baseline"
362// MPModelProto stored in a file, and a "delta" to apply to this model.
363message MPModelDeltaProto {
364  optional /*required*/ string baseline_model_file_path = 1;
365
366  // The variable protos listed here will override (via MergeFrom()) the ones
367  // in the baseline model: you only need to specify the fields that change.
368  // To add a new variable, add it with a new variable index (variable indices
369  // still need to span a dense integer interval).
370  // You can't "delete" a variable but you can "neutralize" it by fixing its
371  // value, setting its objective coefficient to zero, and by nullifying all
372  // the terms involving it in the constraints.
373  map<int32, MPVariableProto> variable_overrides = 2;
374
375  // Constraints can be changed (or added) in the same way as variables, see
376  // above. It's mostly like applying MergeFrom(), except that:
377  // - the "var_index" and "coefficient" fields will be overridden like a map:
378  //   if a key pre-exists, we overwrite its value, otherwise we add it.
379  // - if you set the lower bound to -inf and the upper bound to +inf, thus
380  //   effectively neutralizing the constraint, the solver will implicitly
381  //   remove all of the constraint's terms.
382  map<int32, MPConstraintProto> constraint_overrides = 3;
383
384  // NOTE(user): We may also add more deltas, eg. objective offset.
385}
386
387// Next id: 15.
388message MPModelRequest {
389  // The model to be optimized by the server.
390  optional MPModelProto model = 1;
391
392  // The solver type, which will select a specific implementation, and will also
393  // impact the interpretation of the model (i.e. are we solving the problem
394  // as a mixed integer program or are we relaxing it as a continuous linear
395  // program?).
396  // This must remain consistent with MPSolver::OptimizationProblemType.
397  enum SolverType {
398    GLOP_LINEAR_PROGRAMMING = 2;  // Recommended default for LP models.
399    CLP_LINEAR_PROGRAMMING = 0;
400    GLPK_LINEAR_PROGRAMMING = 1;
401    GUROBI_LINEAR_PROGRAMMING = 6;  // Commercial, needs a valid license.
402    XPRESS_LINEAR_PROGRAMMING = 101;  // Commercial, needs a valid license. NOLINT
403    CPLEX_LINEAR_PROGRAMMING = 10;  // Commercial, needs a valid license. NOLINT
404
405    SCIP_MIXED_INTEGER_PROGRAMMING = 3;  // Recommended default for MIP models.
406    GLPK_MIXED_INTEGER_PROGRAMMING = 4;
407    CBC_MIXED_INTEGER_PROGRAMMING = 5;
408    GUROBI_MIXED_INTEGER_PROGRAMMING = 7;  // Commercial, needs a valid license.
409    XPRESS_MIXED_INTEGER_PROGRAMMING = 102;  // Commercial, needs a valid license. NOLINT
410    CPLEX_MIXED_INTEGER_PROGRAMMING = 11;  // Commercial, needs a valid license. NOLINT
411    BOP_INTEGER_PROGRAMMING = 12;
412
413    // WARNING: This solver will currently interpret all variables as integer,
414    // so any solution you get will be valid, but the optimal might be far away
415    // for the real one (when you authorise non-integer value for continuous
416    // variables).
417    SAT_INTEGER_PROGRAMMING = 14;
418
419    KNAPSACK_MIXED_INTEGER_PROGRAMMING = 13;
420  }
421  optional SolverType solver_type = 2;
422
423  // Maximum time to be spent by the solver to solve 'model'. If the server is
424  // busy and the RPC's deadline_left is less than this, it will immediately
425  // give up and return an error, without even trying to solve.
426  //
427  // The client can use this to have a guarantee on how much time the
428  // solver will spend on the problem (unless it finds and proves
429  // an optimal solution more quickly).
430  //
431  // If not specified, the time limit on the solver is the RPC's deadline_left.
432  optional double solver_time_limit_seconds = 3;
433
434  // If this is set, then EnableOutput() will be set on the internal MPSolver
435  // that solves the model.
436  // WARNING: if you set this on a request to prod servers, it will be rejected
437  // and yield the RPC Application Error code MPSOLVER_SOLVER_TYPE_UNAVAILABLE.
438  optional bool enable_internal_solver_output = 4 [default = false];
439
440  // Advanced usage. Solver-specific parameters in the solver's own format,
441  // different for each solver. For example, if you use SCIP and you want to
442  // stop the solve earlier than the time limit if it reached a solution that is
443  // at most 1% away from the optimal, you can set this to "limits/gap=0.01".
444  //
445  // Note however that there is no "security" mechanism in place so it is up to
446  // the client to make sure that the given options don't make the solve
447  // non thread safe or use up too much memory for instance.
448  //
449  // If the option format is not understood by the solver, the request will be
450  // rejected and yield an RPC Application error with code
451  // MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS, unless you have set
452  // ignore_solver_specific_parameters_failure=true (in which case they are
453  // simply ignored).
454  optional string solver_specific_parameters = 5;
455  optional bool ignore_solver_specific_parameters_failure = 9 [default = false];
456
457
458  // Advanced usage: model "delta". If used, "model" must be unset. See the
459  // definition of MPModelDeltaProto.
460  optional MPModelDeltaProto model_delta = 8;
461
462
463
464  // Controls the recovery of additional solutions, if any, saved by the
465  // underlying solver back in the MPSolutionResponse.additional_solutions.
466  // The repeated field will be length
467  //    min(populate_addition_solutions_up_to,
468  //        #additional_solutions_available_in_underlying_solver)
469  // These additional solutions may have a worse objective than the main
470  // solution returned in the response.
471  optional int32 populate_additional_solutions_up_to = 11 [default = 0];
472
473}
474
475
476// Status returned by the solver. They follow a hierarchical nomenclature, to
477// allow us to add more enum values in the future. Clients should use
478// InCategory() to match these enums, with the following C++ pseudo-code:
479//
480// bool InCategory(MPSolverResponseStatus status, MPSolverResponseStatus cat) {
481//   if (cat == MPSOLVER_OPTIMAL) return status == MPSOLVER_OPTIMAL;
482//   while (status > cat) status >>= 4;
483//   return status == cat;
484// }
485enum MPSolverResponseStatus {
486  // Normal responses -- the model was valid, and the solver ran.
487  // These statuses should be "somewhat" repeatable, modulo the fact that the
488  // solver's time limit makes it undeterministic, and could change a FEASIBLE
489  // model to an OPTIMAL and vice-versa (the others, except NOT_SOLVED, should
490  // normally be deterministic). Also, the solver libraries can be buggy.
491
492  // The solver found the proven optimal solution. This is what should be
493  // returned in most cases.
494  //
495  // WARNING: for historical reason, the value is zero, which means that this
496  // value can't have any subcategories.
497  MPSOLVER_OPTIMAL = 0x0;
498
499  // The solver had enough time to find some solution that satisfies all
500  // constraints, but it did not prove optimality (which means it may or may
501  // not have reached the optimal).
502  //
503  // This can happen for large LP models (Linear Programming), and is a frequent
504  // response for time-limited MIPs (Mixed Integer Programming). In the MIP
505  // case, the difference between the solution 'objective_value' and
506  // 'best_objective_bound' fields of the MPSolutionResponse will give an
507  // indication of how far this solution is from the optimal one.
508  MPSOLVER_FEASIBLE = 0x1;
509
510  // The model does not have any solution, according to the solver (which
511  // "proved" it, with the caveat that numerical proofs aren't actual proofs),
512  // or based on trivial considerations (eg. a variable whose lower bound is
513  // strictly greater than its upper bound).
514  MPSOLVER_INFEASIBLE = 0x2;
515
516  // There exist solutions that make the magnitude of the objective value
517  // as large as wanted (i.e. -infinity (resp. +infinity) for a minimization
518  // (resp. maximization) problem.
519  MPSOLVER_UNBOUNDED = 0x3;
520
521  // An error (most probably numerical) occurred.
522  // One likely cause for such errors is a large numerical range among variable
523  // coefficients (eg. 1e-16, 1e20), in which case one should try to shrink it.
524  MPSOLVER_ABNORMAL = 0x4;
525
526  // The solver did not have a chance to diagnose the model in one of the
527  // categories above.
528  MPSOLVER_NOT_SOLVED = 0x6;
529  // Like "NOT_SOLVED", but typically used by model validation functions
530  // returning a "model status", to enhance readability of the client code.
531  MPSOLVER_MODEL_IS_VALID = 0x61;
532  // The solve was interrupted by the user, and the solver didn't have time to
533  // return a proper status.
534  MPSOLVER_CANCELLED_BY_USER = 0x62;
535  // Special value: the solver status could not be properly translated and is
536  // unknown.
537  MPSOLVER_UNKNOWN_STATUS = 0x63;
538
539  // Model errors. These are always deterministic and repeatable.
540  // They should be accompanied with a string description of the error.
541  MPSOLVER_MODEL_INVALID = 0x5;
542  // Something is wrong with the fields "solution_hint_var_index" and/or
543  // "solution_hint_var_value".
544  MPSOLVER_MODEL_INVALID_SOLUTION_HINT = 0x54;
545  // Something is wrong with the solver_specific_parameters request field.
546  MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS = 0x55;
547
548  // Implementation error: the requested solver implementation is not
549  // available (see MPModelRequest.solver_type).
550  // The linear solver binary was probably not linked with the required library,
551  // eg //ortools/linear_solver:linear_solver_scip for SCIP.
552  MPSOLVER_SOLVER_TYPE_UNAVAILABLE = 0x7;
553  // Some of the selected options were incompatible, e.g. a cancellable solve
554  // was requested via SolverClient::SolveMipRemotely() with an underlying
555  // solver that doesn't support cancellation. status_str should contain a
556  // description of the issue.
557  MPSOLVER_INCOMPATIBLE_OPTIONS = 0x71;
558
559}
560
561message MPSolution {
562  optional double objective_value = 1;
563  repeated double variable_value = 2 [packed = true];
564}
565
566message MPSolveInfo {
567  // How much wall time (resp. user time) elapsed during the Solve() of the
568  // underlying solver library. "wall" time and "user" time are to be
569  // interpreted like for the "time" command in bash (see "help time").
570  // In particular, "user time" is CPU time and can be greater than wall time
571  // when using several threads.
572  optional double solve_wall_time_seconds = 1;
573  optional double solve_user_time_seconds = 2;
574}
575
576// Next id: 11.
577message MPSolutionResponse {
578  // Result of the optimization.
579  optional /*required*/ MPSolverResponseStatus status = 1
580      [default = MPSOLVER_UNKNOWN_STATUS];
581
582  // Human-readable string giving more details about the status. For example,
583  // when the status is MPSOLVER_INVALID_MODE, this can hold a description of
584  // why the model is invalid.
585  // This isn't always filled: don't depend on its value or even its presence.
586  optional string status_str = 7;
587
588  // Objective value corresponding to the "variable_value" below, taking into
589  // account the source "objective_offset" and "objective_coefficient".
590  // This is set iff 'status' is OPTIMAL or FEASIBLE.
591  optional double objective_value = 2;
592
593  // This field is only filled for MIP problems. For a minimization problem,
594  // this is a lower bound on the optimal objective value. For a maximization
595  // problem, it is an upper bound. It is only filled if the status is OPTIMAL
596  // or FEASIBLE. In the former case, best_objective_bound should be equal to
597  // objective_value (modulo numerical errors).
598  optional double best_objective_bound = 5;
599
600  // Variable values in the same order as the MPModelProto::variable field.
601  // This is a dense representation. These are set iff 'status' is OPTIMAL or
602  // FEASIBLE.
603  repeated double variable_value = 3 [packed = true];
604
605  // Contains extra information about the solve, populated if the underlying
606  // solver (and its interface) supports it. As of 2021/07/19 this is supported
607  // by SCIP and Gurobi proto solves.
608  optional MPSolveInfo solve_info = 10;
609
610  // [Advanced usage.]
611  // Values of the dual variables values in the same order as the
612  // MPModelProto::constraint field. This is a dense representation.
613  // These are not set if the problem was solved with a MIP solver (even if
614  // it is actually a linear program).
615  // These are set iff 'status' is OPTIMAL or FEASIBLE.
616  repeated double dual_value = 4 [packed = true];
617
618  // [Advanced usage.]
619  // Values of the reduced cost of the variables in the same order as the
620  // MPModelProto::variable. This is a dense representation.
621  // These are not set if the problem was solved with a MIP solver (even if it
622  // is actually a linear program).
623  // These are set iff 'status' is OPTIMAL or FEASIBLE.
624  repeated double reduced_cost = 6 [packed = true];
625
626  // [Advanced usage.]
627  // If `MPModelRequest.populate_additional_solutions_up_to` > 0, up to that
628  // number of additional solutions may be populated here, if available. These
629  // additional solutions are different than the main solution described by the
630  // above fields `objective_value` and `variable_value`.
631  repeated MPSolution additional_solutions = 8;
632
633}
634