589 lines
26 KiB
Protocol Buffer
589 lines
26 KiB
Protocol Buffer
// Copyright 2010-2018 Google LLC
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Linear Programming Protocol Buffers.
|
|
//
|
|
// The protocol buffers below make it possible to store and transfer the
|
|
// representation of Linear and Mixed-Integer Programs.
|
|
//
|
|
// A Linear Program (LP) is a mathematical optimization model with a linear
|
|
// objective function, and linear equality and inequality constraints.
|
|
// The goal is to achieve the best outcome (such as maximum profit or lowest
|
|
// cost) by modeling the real-world problem at hand using linear functions.
|
|
// In a Mixed Integer Program (MIP), some variables may also be constrained to
|
|
// take integer values.
|
|
//
|
|
// Check ./linear_solver.h and Wikipedia for more detail:
|
|
// http://en.wikipedia.org/wiki/Linear_programming
|
|
//
|
|
|
|
syntax = "proto2";
|
|
|
|
option java_package = "com.google.ortools.linearsolver";
|
|
option java_multiple_files = true;
|
|
|
|
// import "google/protobuf/wrappers.proto";
|
|
import "ortools/util/optional_boolean.proto";
|
|
|
|
package operations_research;
|
|
|
|
// A variable is always constrained in the form:
|
|
// lower_bound <= x <= upper_bound
|
|
// where lower_bound and upper_bound:
|
|
// - Can form a singleton: x = constant = lower_bound = upper_bound.
|
|
// - Can form a finite interval: lower_bound <= x <= upper_bound. (x is boxed.)
|
|
// - Can form a semi-infinite interval.
|
|
// - lower_bound = -infinity: x <= upper_bound.
|
|
// - upper_bound = +infinity: x >= lower_bound.
|
|
// - Can form the infinite interval: lower_bound = -infinity and
|
|
// upper_bound = +infinity, x is free.
|
|
// MPVariableProto furthermore stores:
|
|
// - The coefficient of the variable in the objective.
|
|
// - Whether the variable is integer.
|
|
message MPVariableProto {
|
|
// lower_bound must be <= upper_bound.
|
|
optional double lower_bound = 1 [default = -inf];
|
|
optional double upper_bound = 2 [default = inf];
|
|
|
|
// The coefficient of the variable in the objective. Must be finite.
|
|
optional double objective_coefficient = 3 [default = 0.0];
|
|
|
|
// True if the variable is constrained to be integer.
|
|
// Ignored if MPModelProto::solver_type is *LINEAR_PROGRAMMING*.
|
|
optional bool is_integer = 4 [default = false];
|
|
|
|
// The name of the variable.
|
|
optional string name = 5 [default = ""];
|
|
|
|
optional int32 branching_priority = 6 [default = 0];
|
|
}
|
|
|
|
// A linear constraint is always of the form:
|
|
// lower_bound <= sum of linear term elements <= upper_bound,
|
|
// where lower_bound and upper_bound:
|
|
// - Can form a singleton: lower_bound == upper_bound. The constraint is an
|
|
// equation.
|
|
// - Can form a finite interval [lower_bound, upper_bound]. The constraint is
|
|
// both lower- and upper-bounded, i.e. "boxed".
|
|
// - Can form a semi-infinite interval. lower_bound = -infinity: the constraint
|
|
// is upper-bounded. upper_bound = +infinity: the constraint is lower-bounded.
|
|
// - Can form the infinite interval: lower_bound = -infinity and
|
|
// upper_bound = +infinity. The constraint is free.
|
|
message MPConstraintProto {
|
|
// var_index[i] is the variable index (w.r.t. to "variable" field of
|
|
// MPModelProto) of the i-th linear term involved in this constraint, and
|
|
// coefficient[i] is its coefficient. Only the terms with non-zero
|
|
// coefficients need to appear. var_index may not contain duplicates.
|
|
repeated int32 var_index = 6 [packed = true];
|
|
repeated double coefficient = 7 [packed = true]; // Must be finite.
|
|
|
|
// lower_bound must be <= upper_bound.
|
|
optional double lower_bound = 2 [default = -inf];
|
|
optional double upper_bound = 3 [default = inf];
|
|
|
|
// The name of the constraint.
|
|
optional string name = 4 [default = ""];
|
|
|
|
// [Advanced usage: do not use this if you don't know what you're doing.]
|
|
// A lazy constraint is handled differently by the core solving engine, but
|
|
// it does not change the result. It may or may not impact the performance.
|
|
// For more info see: http://tinyurl.com/lazy-constraints.
|
|
optional bool is_lazy = 5 [default = false];
|
|
}
|
|
|
|
// General constraints. See each individual proto type for more information.
|
|
message MPGeneralConstraintProto {
|
|
// The name of the constraint.
|
|
optional string name = 1 [default = ""];
|
|
|
|
oneof general_constraint {
|
|
MPIndicatorConstraint indicator_constraint = 2;
|
|
MPSosConstraint sos_constraint = 3;
|
|
MPQuadraticConstraint quadratic_constraint = 4;
|
|
MPAbsConstraint abs_constraint = 5;
|
|
// All variables in "and" constraints must be Boolean.
|
|
// resultant_var = and(var_1, var_2... var_n)
|
|
MPArrayConstraint and_constraint = 6;
|
|
// All variables in "or" constraints must be Boolean.
|
|
// resultant_var = or(var_1, var_2... var_n)
|
|
MPArrayConstraint or_constraint = 7;
|
|
// resultant_var = min(var_1, var_2, ..., constant)
|
|
MPArrayWithConstantConstraint min_constraint = 8;
|
|
// resultant_var = max(var_1, var_2, ..., constant)
|
|
MPArrayWithConstantConstraint max_constraint = 9;
|
|
}
|
|
}
|
|
|
|
// Indicator constraints encode the activation or deactivation of linear
|
|
// constraints given the value of one Boolean variable in the model. For
|
|
// example:
|
|
// y = 0 => 2 * x1 + 3 * x2 >= 42
|
|
// The 2 * x1 + 3 * x2 >= 42 constraint is only active if the variable y is
|
|
// equal to 0.
|
|
// As of 2019/04, only SCIP, CP-SAT and Gurobi support this constraint type.
|
|
message MPIndicatorConstraint {
|
|
// Variable index (w.r.t. the "variable" field of MPModelProto) of the Boolean
|
|
// variable used as indicator.
|
|
optional int32 var_index = 1;
|
|
|
|
// Value the above variable should take. Must be 0 or 1.
|
|
optional int32 var_value = 2;
|
|
|
|
// The constraint activated by the indicator variable.
|
|
optional MPConstraintProto constraint = 3;
|
|
}
|
|
|
|
// Special Ordered Set (SOS) constraints of type 1 or 2.
|
|
// See https://en.wikipedia.org/wiki/Special_ordered_set
|
|
// As of 2019/04, only SCIP and Gurobi support this constraint type.
|
|
message MPSosConstraint {
|
|
enum Type {
|
|
// At most one variable in `var_index` must be non-zero.
|
|
SOS1_DEFAULT = 0;
|
|
// At most two consecutive variables from `var_index` can be non-zero (i.e.
|
|
// for some i, var_index[i] and var_index[i+1]). See
|
|
// http://www.eudoxus.com/lp-training/5/5-6-special-ordered-sets-of-type-2
|
|
SOS2 = 1;
|
|
}
|
|
optional Type type = 1 [default = SOS1_DEFAULT];
|
|
|
|
// Variable index (w.r.t. the "variable" field of MPModelProto) of the
|
|
// variables in the SOS.
|
|
repeated int32 var_index = 2;
|
|
|
|
// Optional: SOS weights. If non-empty, must be of the same size as
|
|
// "var_index", and strictly increasing. If empty and required by the
|
|
// underlying solver, the 1..n sequence will be given as weights.
|
|
// SUBTLE: The weights can help the solver make branch-and-bound decisions
|
|
// that fit the underlying optimization model: after each LP relaxation, it
|
|
// will compute the "average weight" of the SOS variables, weighted by value
|
|
// (this is confusing: here we're using the values as weights), and the binary
|
|
// branch decision will be: is the non-zero variable above or below that?
|
|
// (weights are strictly monotonous, so the "cutoff" average weight
|
|
// corresponds to a "cutoff" index in the var_index sequence).
|
|
repeated double weight = 3;
|
|
}
|
|
|
|
// Quadratic constraints of the form lb <= sum a_i x_i + sum b_ij x_i x_j <= ub,
|
|
// where a, b, lb and ub are constants, and x are the model's variables.
|
|
// Quadratic matrices that are Positive Semi-Definite, Second-Order Cones or
|
|
// rotated Second-Order Cones are always accepted. Other forms may or may not be
|
|
// accepted depending on the underlying solver used.
|
|
// See https://scip.zib.de/doc/html/cons__quadratic_8h.php and
|
|
// https://www.gurobi.com/documentation/8.1/refman/constraints.html#subsubsection:QuadraticConstraints
|
|
message MPQuadraticConstraint {
|
|
// Sparse representation of linear terms in the quadratic constraint, where
|
|
// term i is var_index[i] * coefficient[i].
|
|
// `var_index` are variable indices w.r.t the "variable" field in
|
|
// MPModelProto.
|
|
repeated int32 var_index = 1;
|
|
repeated double coefficient = 2; // Must be finite.
|
|
|
|
// Sparse representation of quadratic terms in the quadratic constraint, where
|
|
// term i is qvar1_index[i] * qvar2_index[i] * qcoefficient[i].
|
|
// `qvar1_index` and `qvar2_index` are variable indices w.r.t the "variable"
|
|
// field in MPModelProto.
|
|
// `qvar1_index`, `qvar2_index` and `coefficients` must have the same size.
|
|
// If the same unordered pair (qvar1_index, qvar2_index) appears several
|
|
// times, the sum of all of the associated coefficients will be applied.
|
|
repeated int32 qvar1_index = 3;
|
|
repeated int32 qvar2_index = 4;
|
|
repeated double qcoefficient = 5; // Must be finite.
|
|
|
|
// lower_bound must be <= upper_bound.
|
|
optional double lower_bound = 6 [default = -inf];
|
|
optional double upper_bound = 7 [default = inf];
|
|
}
|
|
|
|
// Sets a variable's value to the absolute value of another variable.
|
|
message MPAbsConstraint {
|
|
// Variable indices are relative to the "variable" field in MPModelProto.
|
|
// resultant_var = abs(var)
|
|
optional int32 var_index = 1;
|
|
optional int32 resultant_var_index = 2;
|
|
}
|
|
|
|
// Sets a variable's value equal to a function on a set of variables.
|
|
message MPArrayConstraint {
|
|
// Variable indices are relative to the "variable" field in MPModelProto.
|
|
repeated int32 var_index = 1;
|
|
optional int32 resultant_var_index = 2;
|
|
}
|
|
|
|
// Sets a variable's value equal to a function on a set of variables and,
|
|
// optionally, a constant.
|
|
message MPArrayWithConstantConstraint {
|
|
// Variable indices are relative to the "variable" field in MPModelProto.
|
|
// resultant_var = f(var_1, var_2, ..., constant)
|
|
repeated int32 var_index = 1;
|
|
optional double constant = 2;
|
|
optional int32 resultant_var_index = 3;
|
|
}
|
|
|
|
// Quadratic part of a model's objective. Added with other objectives (such as
|
|
// linear), this creates the model's objective function to be optimized.
|
|
// Note: the linear part of the objective currently needs to be specified in the
|
|
// MPVariableProto.objective_coefficient fields. If you'd rather have a
|
|
// dedicated linear array here, talk to or-core-team@
|
|
message MPQuadraticObjective {
|
|
// Sparse representation of quadratic terms in the objective function, where
|
|
// term i is qvar1_index[i] * qvar2_index[i] * coefficient[i].
|
|
// `qvar1_index` and `qvar2_index` are variable indices w.r.t the "variable"
|
|
// field in MPModelProto.
|
|
// `qvar1_index`, `qvar2_index` and `coefficients` must have the same size.
|
|
// If the same unordered pair (qvar1_index, qvar2_index) appears several
|
|
// times, the sum of all of the associated coefficients will be applied.
|
|
repeated int32 qvar1_index = 1;
|
|
repeated int32 qvar2_index = 2;
|
|
repeated double coefficient = 3; // Must be finite.
|
|
}
|
|
|
|
// This message encodes a partial (or full) assignment of the variables of a
|
|
// MPModelProto problem. The indices in var_index should be unique and valid
|
|
// variable indices of the associated problem.
|
|
message PartialVariableAssignment {
|
|
repeated int32 var_index = 1 [packed = true];
|
|
repeated double var_value = 2 [packed = true];
|
|
}
|
|
|
|
// MPModelProto contains all the information for a Linear Programming model.
|
|
message MPModelProto {
|
|
// All the variables appearing in the model.
|
|
repeated MPVariableProto variable = 3;
|
|
|
|
// All the constraints appearing in the model.
|
|
repeated MPConstraintProto constraint = 4;
|
|
|
|
// All the general constraints appearing in the model. Note that not all
|
|
// solvers support all types of general constraints.
|
|
repeated MPGeneralConstraintProto general_constraint = 7;
|
|
|
|
// True if the problem is a maximization problem. Minimize by default.
|
|
optional bool maximize = 1 [default = false];
|
|
|
|
// Offset for the objective function. Must be finite.
|
|
optional double objective_offset = 2 [default = 0.0];
|
|
|
|
// Optionally, a quadratic objective.
|
|
// As of 2019/06, only SCIP and Gurobi support quadratic objectives.
|
|
optional MPQuadraticObjective quadratic_objective = 8;
|
|
|
|
// Name of the model.
|
|
optional string name = 5 [default = ""];
|
|
|
|
// Solution hint.
|
|
//
|
|
// If a feasible or almost-feasible solution to the problem is already known,
|
|
// it may be helpful to pass it to the solver so that it can be used. A solver
|
|
// that supports this feature will try to use this information to create its
|
|
// initial feasible solution.
|
|
//
|
|
// Note that it may not always be faster to give a hint like this to the
|
|
// solver. There is also no guarantee that the solver will use this hint or
|
|
// try to return a solution "close" to this assignment in case of multiple
|
|
// optimal solutions.
|
|
optional PartialVariableAssignment solution_hint = 6;
|
|
}
|
|
|
|
// To support 'unspecified' double value in proto3, the simplest is to wrap
|
|
// any double value in a nested message (has_XXX works for message fields).
|
|
// We don't use google/protobuf/wrappers.proto because depending on it makes
|
|
// the following android integration test fail:
|
|
// http://sponge/c4bce1fd-41bd-4d0b-b4ca-fc04d4d64621
|
|
message OptionalDouble {
|
|
optional double value = 1;
|
|
}
|
|
|
|
// MPSolverCommonParameters holds advanced usage parameters that apply to any of
|
|
// the solvers we support.
|
|
// All of the fields in this proto can have a value of unspecified. In this
|
|
// case each inner solver will use their own safe defaults.
|
|
// Some values won't be supported by some solvers. The behavior in that case is
|
|
// not defined yet.
|
|
message MPSolverCommonParameters {
|
|
// The solver stops if the relative MIP gap reaches this value or below.
|
|
// The relative MIP gap is an upper bound of the relative distance to the
|
|
// optimum, and it is defined as:
|
|
//
|
|
// abs(best_bound - incumbent) / abs(incumbent) [Gurobi]
|
|
// abs(best_bound - incumbent) / min(abs(best_bound), abs(incumbent)) [SCIP]
|
|
//
|
|
// where "incumbent" is the objective value of the best solution found so far
|
|
// (i.e., lowest when minimizing, highest when maximizing), and "best_bound"
|
|
// is the tightest bound of the objective determined so far (i.e., highest
|
|
// when minimizing, and lowest when maximizing). The MIP Gap is sensitive to
|
|
// objective offset. If the denominator is 0 the MIP Gap is INFINITY for SCIP
|
|
// and Gurobi. Of note, "incumbent" and "best bound" are called "primal bound"
|
|
// and "dual bound" in SCIP, respectively.
|
|
// Ask or-core-team@ for other solvers.
|
|
optional OptionalDouble relative_mip_gap = 1;
|
|
|
|
// Tolerance for primal feasibility of basic solutions: this is the maximum
|
|
// allowed error in constraint satisfiability.
|
|
// For SCIP this includes integrality constraints. For Gurobi it does not, you
|
|
// need to set the custom parameter IntFeasTol.
|
|
optional OptionalDouble primal_tolerance = 2;
|
|
|
|
// Tolerance for dual feasibility.
|
|
// For SCIP and Gurobi this is the feasibility tolerance for reduced costs in
|
|
// LP solution: reduced costs must all be smaller than this value in the
|
|
// improving direction in order for a model to be declared optimal.
|
|
// Not supported for other solvers.
|
|
optional OptionalDouble dual_tolerance = 3;
|
|
|
|
enum LPAlgorithmValues {
|
|
LP_ALGO_UNSPECIFIED = 0;
|
|
LP_ALGO_DUAL = 1; // Dual simplex.
|
|
LP_ALGO_PRIMAL = 2; // Primal simplex.
|
|
LP_ALGO_BARRIER = 3; // Barrier algorithm.
|
|
}
|
|
|
|
// Algorithm to solve linear programs.
|
|
// Ask or-core-team@ if you want to know what this does exactly.
|
|
optional LPAlgorithmValues lp_algorithm = 4 [default = LP_ALGO_UNSPECIFIED];
|
|
|
|
// Gurobi and SCIP enable presolve by default.
|
|
// Ask or-core-team@ for other solvers.
|
|
optional OptionalBoolean presolve = 5 [default = BOOL_UNSPECIFIED];
|
|
|
|
// Enable automatic scaling of matrix coefficients and objective. Available
|
|
// for Gurobi and GLOP.
|
|
// Ask or-core-team@ if you want more details.
|
|
optional OptionalBoolean scaling = 7 [default = BOOL_UNSPECIFIED];
|
|
}
|
|
|
|
// Encodes a full MPModelProto by way of referencing to a "baseline"
|
|
// MPModelProto stored in a file, and a "delta" to apply to this model.
|
|
message MPModelDeltaProto {
|
|
optional /*required*/ string baseline_model_file_path = 1;
|
|
|
|
// The variable protos listed here will override (via MergeFrom()) the ones
|
|
// in the baseline model: you only need to specify the fields that change.
|
|
// To add a new variable, add it with a new variable index (variable indices
|
|
// still need to span a dense integer interval).
|
|
// You can't "delete" a variable but you can "neutralize" it by fixing its
|
|
// value, setting its objective coefficient to zero, and by nullifying all
|
|
// the terms involving it in the constraints.
|
|
map<int32, MPVariableProto> variable_overrides = 2;
|
|
|
|
// Constraints can be changed (or added) in the same way as variables, see
|
|
// above. It's mostly like applying MergeFrom(), except that:
|
|
// - the "var_index" and "coefficient" fields will be overridden like a map:
|
|
// if a key pre-exists, we overwrite its value, otherwise we add it.
|
|
// - if you set the lower bound to -inf and the upper bound to +inf, thus
|
|
// effectively neutralizing the constraint, the solver will implicitly
|
|
// remove all of the constraint's terms.
|
|
map<int32, MPConstraintProto> constraint_overrides = 3;
|
|
|
|
// NOTE(user): We may also add more deltas, eg. objective offset.
|
|
}
|
|
|
|
// Next id: 9.
|
|
message MPModelRequest {
|
|
// The model to be optimized by the server.
|
|
optional MPModelProto model = 1;
|
|
|
|
// The solver type, which will select a specific implementation, and will also
|
|
// impact the interpretation of the model (i.e. are we solving the problem
|
|
// as a mixed integer program or are we relaxing it as a continuous linear
|
|
// program?).
|
|
// This must remain consistent with MPSolver::OptimizationProblemType.
|
|
enum SolverType {
|
|
GLOP_LINEAR_PROGRAMMING = 2; // Recommended default for LP models.
|
|
CLP_LINEAR_PROGRAMMING = 0;
|
|
GLPK_LINEAR_PROGRAMMING = 1;
|
|
GUROBI_LINEAR_PROGRAMMING = 6; // Commercial, needs a valid license.
|
|
XPRESS_LINEAR_PROGRAMMING = 101; // Commercial, needs a valid license.
|
|
CPLEX_LINEAR_PROGRAMMING = 10; // Commercial, needs a valid
|
|
// license.
|
|
|
|
SCIP_MIXED_INTEGER_PROGRAMMING = 3; // Recommended default for MIP models.
|
|
GLPK_MIXED_INTEGER_PROGRAMMING = 4;
|
|
CBC_MIXED_INTEGER_PROGRAMMING = 5;
|
|
GUROBI_MIXED_INTEGER_PROGRAMMING = 7; // Commercial, needs a valid license.
|
|
XPRESS_MIXED_INTEGER_PROGRAMMING =
|
|
102; // Commercial, needs a valid license.
|
|
CPLEX_MIXED_INTEGER_PROGRAMMING = 11; // Commercial, needs a
|
|
// valid license.
|
|
BOP_INTEGER_PROGRAMMING = 12;
|
|
|
|
// WARNING: This solver will currently interpret all variables as integer,
|
|
// so any solution you get will be valid, but the optimal might be far away
|
|
// for the real one (when you authorise non-integer value for continuous
|
|
// variables).
|
|
SAT_INTEGER_PROGRAMMING = 14;
|
|
|
|
KNAPSACK_MIXED_INTEGER_PROGRAMMING = 13;
|
|
}
|
|
optional SolverType solver_type = 2;
|
|
|
|
// Maximum time to be spent by the solver to solve 'model'. If the server is
|
|
// busy and the RPC's deadline_left is less than this, it will immediately
|
|
// give up and return an error, without even trying to solve.
|
|
//
|
|
// The client can use this to have a guarantee on how much time the
|
|
// solver will spend on the problem (unless it finds and proves
|
|
// an optimal solution more quickly).
|
|
//
|
|
// If not specified, the time limit on the solver is the RPC's deadline_left.
|
|
optional double solver_time_limit_seconds = 3;
|
|
|
|
// If this is set, then EnableOutput() will be set on the internal MPSolver
|
|
// that solves the model.
|
|
// WARNING: if you set this on a request to prod servers, it will be rejected
|
|
// and yield the RPC Application Error code MPSOLVER_SOLVER_TYPE_UNAVAILABLE.
|
|
optional bool enable_internal_solver_output = 4 [default = false];
|
|
|
|
// Advanced usage. Solver-specific parameters in the solver's own format,
|
|
// different for each solver. For example, if you use SCIP and you want to
|
|
// stop the solve earlier than the time limit if it reached a solution that is
|
|
// at most 1% away from the optimal, you can set this to "limits/gap=0.01".
|
|
//
|
|
// Note however that there is no "security" mechanism in place so it is up to
|
|
// the client to make sure that the given options don't make the solve
|
|
// non thread safe or use up too much memory for instance.
|
|
//
|
|
// If the option format is not understood by the solver, the request will be
|
|
// rejected and yield an RPC Application error with code
|
|
// MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS.
|
|
optional string solver_specific_parameters = 5;
|
|
|
|
|
|
// Advanced usage: model "delta". If used, "model" must be unset. See the
|
|
// definition of MPModelDeltaProto.
|
|
optional MPModelDeltaProto model_delta = 8;
|
|
|
|
}
|
|
|
|
// Status returned by the solver. They follow a hierarchical nomenclature, to
|
|
// allow us to add more enum values in the future. Clients should use
|
|
// InCategory() to match these enums, with the following C++ pseudo-code:
|
|
//
|
|
// bool InCategory(MPSolverResponseStatus status, MPSolverResponseStatus cat) {
|
|
// if (cat == MPSOLVER_OPTIMAL) return status == MPSOLVER_OPTIMAL;
|
|
// while (status > cat) status >>= 4;
|
|
// return status == cat;
|
|
// }
|
|
enum MPSolverResponseStatus {
|
|
// Normal responses -- the model was valid, and the solver ran.
|
|
// These statuses should be "somewhat" repeatable, modulo the fact that the
|
|
// solver's time limit makes it undeterministic, and could change a FEASIBLE
|
|
// model to an OPTIMAL and vice-versa (the others, except NOT_SOLVED, should
|
|
// normally be deterministic). Also, the solver libraries can be buggy.
|
|
|
|
// The solver found the proven optimal solution. This is what should be
|
|
// returned in most cases.
|
|
//
|
|
// WARNING: for historical reason, the value is zero, which means that this
|
|
// value can't have any subcategories.
|
|
MPSOLVER_OPTIMAL = 0x0;
|
|
|
|
// The solver had enough time to find some solution that satisfies all
|
|
// constraints, but it did not prove optimality (which means it may or may
|
|
// not have reached the optimal).
|
|
//
|
|
// This can happen for large LP models (Linear Programming), and is a frequent
|
|
// response for time-limited MIPs (Mixed Integer Programming). In the MIP
|
|
// case, the difference between the solution 'objective_value' and
|
|
// 'best_objective_bound' fields of the MPSolutionResponse will give an
|
|
// indication of how far this solution is from the optimal one.
|
|
MPSOLVER_FEASIBLE = 0x1;
|
|
|
|
// The model does not have any solution, according to the solver (which
|
|
// "proved" it, with the caveat that numerical proofs aren't actual proofs),
|
|
// or based on trivial considerations (eg. a variable whose lower bound is
|
|
// strictly greater than its upper bound).
|
|
MPSOLVER_INFEASIBLE = 0x2;
|
|
|
|
// There exist solutions that make the magnitude of the objective value
|
|
// as large as wanted (i.e. -infinity (resp. +infinity) for a minimization
|
|
// (resp. maximization) problem.
|
|
MPSOLVER_UNBOUNDED = 0x3;
|
|
|
|
// An error (most probably numerical) occurred.
|
|
// One likely cause for such errors is a large numerical range among variable
|
|
// coefficients (eg. 1e-16, 1e20), in which case one should try to shrink it.
|
|
MPSOLVER_ABNORMAL = 0x4;
|
|
|
|
// The solver did not have a chance to diagnose the model in one of the
|
|
// categories above.
|
|
MPSOLVER_NOT_SOLVED = 0x6;
|
|
// Like "NOT_SOLVED", but typically used by model validation functions
|
|
// returning a "model status", to enhance readability of the client code.
|
|
MPSOLVER_MODEL_IS_VALID = 0x61;
|
|
// Special value: the solver status could not be properly translated and is
|
|
// unknown.
|
|
MPSOLVER_UNKNOWN_STATUS = 0x63;
|
|
|
|
// Model errors. These are always deterministic and repeatable.
|
|
// They should be accompanied with a string description of the error.
|
|
MPSOLVER_MODEL_INVALID = 0x5;
|
|
// Something is wrong with the fields "solution_hint_var_index" and/or
|
|
// "solution_hint_var_value".
|
|
MPSOLVER_MODEL_INVALID_SOLUTION_HINT = 0x54;
|
|
// Something is wrong with the solver_specific_parameters request field.
|
|
MPSOLVER_MODEL_INVALID_SOLVER_PARAMETERS = 0x55;
|
|
|
|
// Implementation error: the requested solver implementation is not
|
|
// available (see MPModelRequest.solver_type).
|
|
// The linear solver binary was probably not linked with the required library,
|
|
// eg //ortools/linear_solver:linear_solver_scip for SCIP.
|
|
MPSOLVER_SOLVER_TYPE_UNAVAILABLE = 0x7;
|
|
|
|
}
|
|
|
|
message MPSolutionResponse {
|
|
// Result of the optimization.
|
|
optional /*required*/ MPSolverResponseStatus status = 1
|
|
[default = MPSOLVER_UNKNOWN_STATUS];
|
|
|
|
// Human-readable string giving more details about the status. For example,
|
|
// when the status is MPSOLVER_INVALID_MODE, this can hold a description of
|
|
// why the model is invalid.
|
|
// This isn't always filled: don't depend on its value or even its presence.
|
|
optional string status_str = 7;
|
|
|
|
// Objective value corresponding to the "variable_value" below, taking into
|
|
// account the source "objective_offset" and "objective_coefficient".
|
|
// This is set iff 'status' is OPTIMAL or FEASIBLE.
|
|
optional double objective_value = 2;
|
|
|
|
// This field is only filled for MIP problems. For a minimization problem,
|
|
// this is a lower bound on the optimal objective value. For a maximization
|
|
// problem, it is an upper bound. It is only filled if the status is OPTIMAL
|
|
// or FEASIBLE. In the former case, best_objective_bound should be equal to
|
|
// objective_value (modulo numerical errors).
|
|
optional double best_objective_bound = 5;
|
|
|
|
// Variable values in the same order as the MPModelProto::variable field.
|
|
// This is a dense representation. These are set iff 'status' is OPTIMAL or
|
|
// FEASIBLE.
|
|
repeated double variable_value = 3 [packed = true];
|
|
|
|
// [Advanced usage.]
|
|
// Values of the dual variables values in the same order as the
|
|
// MPModelProto::constraint field. This is a dense representation.
|
|
// These are not set if the problem was solved with a MIP solver (even if
|
|
// it is actually a linear program).
|
|
// These are set iff 'status' is OPTIMAL or FEASIBLE.
|
|
repeated double dual_value = 4 [packed = true];
|
|
|
|
// [Advanced usage.]
|
|
// Values of the reduced cost of the variables in the same order as the
|
|
// MPModelProto::variable. This is a dense representation.
|
|
// These are not set if the problem was solved with a MIP solver (even if it
|
|
// is actually a linear program).
|
|
// These are set iff 'status' is OPTIMAL or FEASIBLE.
|
|
repeated double reduced_cost = 6 [packed = true];
|
|
}
|