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