Solves the input model and returns the result at once. Use this when you don't need callbacks, incrementality and don't need to track the progress of a solve.
HTTP request
POST https://optimization.googleapis.com/v1/mathopt:solveMathOptModel
The URL uses gRPC Transcoding syntax.
Request body
The request body contains data with the following structure:
JSON representation |
---|
{ "solverType": enum ( |
Fields | |
---|---|
solverType |
Optional. Solver type to numerically solve the problem. Note that if a solver does not support a specific feature in the model, the optimization procedure won't be successful. |
model |
Required. A mathematical representation of the optimization problem to solve. |
parameters |
Optional. Parameters to control a single solve. The enableOutput parameter is handled specifically. For solvers that support messages callbacks, setting it to true will have the server register a message callback. The resulting messages will be returned in SolveMathOptModelResponse.messages. For other solvers, setting enableOutput to true will result in an error. |
modelParameters |
Optional. Parameters to control a single solve that are specific to the input model (see SolveParametersProto for model independent parameters). |
Response body
Response for a unary remote solve in MathOpt.
If successful, the response body contains data with the following structure:
JSON representation |
---|
{
"result": {
object ( |
Fields | |
---|---|
result |
Description of the output of solving the model in the request. |
messages[] |
If SolveParametersProto.enable_output has been used, this will contain log messages for solvers that support message callbacks. |
SolverTypeProto
The solvers supported by MathOpt.
Enums | |
---|---|
SOLVER_TYPE_UNSPECIFIED |
|
SOLVER_TYPE_GSCIP |
Solving Constraint Integer Programs (SCIP) solver (third party). Supports LP, MIP, and nonconvex integer quadratic problems. No dual data for LPs is returned though. Prefer GLOP for LPs. |
SOLVER_TYPE_GUROBI |
Gurobi solver (third party). Supports LP, MIP, and nonconvex integer quadratic problems. Generally the fastest option, but has special licensing. |
SOLVER_TYPE_GLOP |
Google's Glop solver. Supports LP with primal and dual simplex methods. |
SOLVER_TYPE_CP_SAT |
Google's CP-SAT solver. Supports problems where all variables are integer and bounded (or implied to be after presolve). Experimental support to rescale and discretize problems with continuous variables. |
SOLVER_TYPE_PDLP |
Google's PDLP solver. Supports LP and convex diagonal quadratic objectives. Uses first order methods rather than simplex. Can solve very large problems. |
SOLVER_TYPE_GLPK |
GNU Linear Programming Kit (GLPK) (third party). Supports MIP and LP. Thread-safety: GLPK use thread-local storage for memory allocations. As a consequence Solver instances must be destroyed on the same thread as they are created or GLPK will crash. It seems OK to call Solver::Solve() from another thread than the one used to create the Solver but it is not documented by GLPK and should be avoided. When solving a LP with the presolver, a solution (and the unbound rays) are only returned if an optimal solution has been found. Else nothing is returned. See glpk-5.0/doc/glpk.pdf page #40 available from glpk-5.0.tar.gz for details. |
SOLVER_TYPE_OSQP |
The Operator Splitting Quadratic Program (OSQP) solver (third party). Supports continuous problems with linear constraints and linear or convex quadratic objectives. Uses a first-order method. |
SOLVER_TYPE_ECOS |
The Embedded Conic Solver (ECOS) (third party). Supports LP and SOCP problems. Uses interior point methods (barrier). |
SOLVER_TYPE_SCS |
The Splitting Conic Solver (SCS) (third party). Supports LP and SOCP problems. Uses a first-order method. |
SOLVER_TYPE_HIGHS |
The HiGHS Solver (third party). Supports LP and MIP problems (convex QPs are unimplemented). |
SOLVER_TYPE_SANTORINI |
MathOpt's reference implementation of a MIP solver. Slow/not recommended for production. Not an LP solver (no dual information returned). |
ModelProto
An optimization problem. MathOpt supports: - Continuous and integer decision variables with optional finite bounds. - Linear and quadratic objectives (single or multiple objectives), either minimized or maximized. - A number of constraints types, including: * Linear constraints * Quadratic constraints * Second-order cone constraints * Logical constraints > SOS1 and SOS2 constraints > Indicator constraints
By default, constraints are represented in "id-to-data" maps. However, we represent linear constraints in a more efficient "struct-of-arrays" format.
JSON representation |
---|
{ "name": string, "variables": { object ( |
Fields | |
---|---|
name |
|
variables |
|
objective |
The primary objective in the model. |
auxiliaryObjectives |
Auxiliary objectives for use in multi-objective models. Map key IDs must be in [0, max(int64)). Each priority, and each nonempty name, must be unique and also distinct from the primary An object containing a list of |
linearConstraints |
|
linearConstraintMatrix |
The variable coefficients for the linear constraints. If a variable involved in this constraint is deleted, it is treated as if it were set to zero. Requirements: * linearConstraintMatrix.row_ids are elements of linearConstraints.ids. * linearConstraintMatrix.column_ids are elements of variables.ids. * Matrix entries not specified are zero. * linearConstraintMatrix.values must all be finite. |
quadraticConstraints |
Quadratic constraints in the model. An object containing a list of |
secondOrderConeConstraints |
Second-order cone constraints in the model. An object containing a list of |
sos1Constraints |
SOS1 constraints in the model, which constrain that at most one An object containing a list of |
sos2Constraints |
SOS2 constraints in the model, which constrain that at most two entries of An object containing a list of |
indicatorConstraints |
Indicator constraints in the model, which enforce that, if a binary "indicator variable" is set to one, then an "implied constraint" must hold. An object containing a list of |
VariablesProto
As used below, we define "#variables" = size(VariablesProto.ids).
JSON representation |
---|
{ "ids": [ string ], "lowerBounds": [ number ], "upperBounds": [ number ], "integers": [ boolean ], "names": [ string ] } |
Fields | |
---|---|
ids[] |
Must be nonnegative and strictly increasing. The max(int64) value can't be used. |
lowerBounds[] |
Should have length equal to #variables, values in [-inf, inf). |
upperBounds[] |
Should have length equal to #variables, values in (-inf, inf]. |
integers[] |
Should have length equal to #variables. Value is false for continuous variables and true for integer variables. |
names[] |
If not set, assumed to be all empty strings. Otherwise, should have length equal to #variables. All nonempty names must be distinct. |
ObjectiveProto
JSON representation |
---|
{ "maximize": boolean, "offset": number, "linearCoefficients": { object ( |
Fields | |
---|---|
maximize |
false is minimize, true is maximize |
offset |
Must be finite and not NaN. |
linearCoefficients |
ObjectiveProto terms that are linear in the decision variables. Requirements: * linearCoefficients.ids are elements of VariablesProto.ids. * VariablesProto not specified correspond to zero. * linearCoefficients.values must all be finite. * linearCoefficients.values can be zero, but this just wastes space. |
quadraticCoefficients |
Objective terms that are quadratic in the decision variables. Requirements in addition to those on SparseDoubleMatrixProto messages: * Each element of quadraticCoefficients.row_ids and each element of quadraticCoefficients.column_ids must be an element of VariablesProto.ids. * The matrix must be upper triangular: for each i, quadraticCoefficients.row_ids[i] <= quadraticCoefficients.column_ids[i]. Notes: * Terms not explicitly stored have zero coefficient. * Elements of quadraticCoefficients.coefficients can be zero, but this just wastes space. |
name |
Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.objectives and AuxiliaryObjectivesUpdatesProto.new_objectives. |
priority |
For multi-objective problems, the priority of this objective relative to the others (lower is more important). This value must be nonnegative. Furthermore, each objective priority in the model must be distinct at solve time. This condition is not validated at the proto level, so models may temporarily have objectives with the same priority. |
SparseDoubleVectorProto
A sparse representation of a vector of doubles.
JSON representation |
---|
{ "ids": [ string ], "values": [ number ] } |
Fields | |
---|---|
ids[] |
Must be sorted (in increasing ordering) with all elements distinct. |
values[] |
Must have equal length to ids. May not contain NaN. |
SparseDoubleMatrixProto
A sparse representation of a matrix of doubles.
The matrix is stored as triples of row id, column id, and coefficient. These three vectors must be of equal length. For all i, the tuple (rowIds[i], columnIds[i]) should be distinct. Entries must be in row major order.
JSON representation |
---|
{ "rowIds": [ string ], "columnIds": [ string ], "coefficients": [ number ] } |
Fields | |
---|---|
rowIds[] |
|
columnIds[] |
|
coefficients[] |
May not contain NaN. |
LinearConstraintsProto
As used below, we define "#linear constraints" = size(LinearConstraintsProto.ids).
JSON representation |
---|
{ "ids": [ string ], "lowerBounds": [ number ], "upperBounds": [ number ], "names": [ string ] } |
Fields | |
---|---|
ids[] |
Must be nonnegative and strictly increasing. The max(int64) value can't be used. |
lowerBounds[] |
Should have length equal to #linear constraints, values in [-inf, inf). |
upperBounds[] |
Should have length equal to #linear constraints, values in (-inf, inf]. |
names[] |
If not set, assumed to be all empty strings. Otherwise, should have length equal to #linear constraints. All nonempty names must be distinct. |
QuadraticConstraintProto
A single quadratic constraint of the form: lb <= sum{linearTerms} + sum{quadraticTerms} <= ub.
If a variable involved in this constraint is deleted, it is treated as if it were set to zero.
JSON representation |
---|
{ "linearTerms": { object ( |
Fields | |
---|---|
linearTerms |
Terms that are linear in the decision variables. In addition to requirements on SparseDoubleVectorProto messages we require that: * linearTerms.ids are elements of VariablesProto.ids. * linearTerms.values must all be finite and not-NaN. Notes: * Variable ids omitted have a corresponding coefficient of zero. * linearTerms.values can be zero, but this just wastes space. |
quadraticTerms |
Terms that are quadratic in the decision variables. In addition to requirements on SparseDoubleMatrixProto messages we require that: * Each element of quadraticTerms.row_ids and each element of quadraticTerms.column_ids must be an element of VariablesProto.ids. * The matrix must be upper triangular: for each i, quadraticTerms.row_ids[i] <= quadraticTerms.column_ids[i]. Notes: * Terms not explicitly stored have zero coefficient. * Elements of quadraticTerms.coefficients can be zero, but this just wastes space. |
lowerBound |
Must have value in [-inf, inf), and be less than or equal to |
upperBound |
Must have value in (-inf, inf], and be greater than or equal to |
name |
Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.quadratic_constraints and QuadraticConstraintUpdatesProto.new_constraints. |
SecondOrderConeConstraintProto
A single second-order cone constraint of the form:
||argumentsToNorm
||_2 <= upperBound
,
where upperBound
and each element of argumentsToNorm
are linear expressions.
If a variable involved in this constraint is deleted, it is treated as if it were set to zero.
JSON representation |
---|
{ "upperBound": { object ( |
Fields | |
---|---|
upperBound |
|
argumentsToNorm[] |
|
name |
Parent messages may have uniqueness requirements on this field; e.g., see |
LinearExpressionProto
A sparse representation of a linear expression (a weighted sum of variables, plus a constant offset).
JSON representation |
---|
{ "ids": [ string ], "coefficients": [ number ], "offset": number } |
Fields | |
---|---|
ids[] |
Ids of variables. Must be sorted (in increasing ordering) with all elements distinct. |
coefficients[] |
Must have equal length to ids. Values must be finite may not be NaN. |
offset |
Must be finite and may not be NaN. |
SosConstraintProto
Data for representing a single SOS1 or SOS2 constraint.
If a variable involved in this constraint is deleted, it is treated as if it were set to zero.
JSON representation |
---|
{
"expressions": [
{
object ( |
Fields | |
---|---|
expressions[] |
The expressions over which to apply the SOS constraint: * SOS1: At most one element takes a nonzero value. * SOS2: At most two elements take nonzero values, and they must be adjacent in the repeated ordering. |
weights[] |
Either empty or of equal length to expressions. If empty, default weights are 1, 2, ... If present, the entries must be unique. |
name |
Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.sos1_constraints and SosConstraintUpdatesProto.new_constraints. |
IndicatorConstraintProto
Data for representing a single indicator constraint of the form: Variable(indicatorId) = (activateOnZero ? 0 : 1) ⇒ lowerBound <= expression <= upperBound.
If a variable involved in this constraint (either the indicator, or appearing in expression
) is deleted, it is treated as if it were set to zero. In particular, deleting the indicator variable means that the indicator constraint is vacuous if activateOnZero
is false, and that it is equivalent to a linear constraint if activateOnZero
is true.
JSON representation |
---|
{
"activateOnZero": boolean,
"expression": {
object ( |
Fields | |
---|---|
activateOnZero |
If true, then if the indicator variable takes value 0, the implied constraint must hold. Otherwise, if the indicator variable takes value 1, then the implied constraint must hold. |
expression |
Must be a valid linear expression with respect to the containing model: * All stated conditions on |
lowerBound |
Must have value in [-inf, inf); cannot be NaN. |
upperBound |
Must have value in (-inf, inf]; cannot be NaN. |
name |
Parent messages may have uniqueness requirements on this field; e.g., see |
indicatorId |
An ID corresponding to a binary variable, or unset. If unset, the indicator constraint is ignored. If set, we require that: * VariablesProto.integers[indicatorId] = true, * VariablesProto.lower_bounds[indicatorId] >= 0, * VariablesProto.upper_bounds[indicatorId] <= 1. These conditions are not validated by MathOpt, but if not satisfied will lead to the solver returning an error upon solving. |
SolveParametersProto
Parameters to control a single solve.
Contains both parameters common to all solvers e.g. timeLimit, and parameters for a specific solver, e.g. gscip. If a value is set in both common and solver specific field, the solver specific setting is used.
The common parameters that are optional and unset or an enum with value unspecified indicate that the solver default is used.
Solver specific parameters for solvers other than the one in use are ignored.
Parameters that depends on the model (e.g. branching priority is set for each variable) are passed in ModelSolveParametersProto.
JSON representation |
---|
{ "timeLimit": string, "enableOutput": boolean, "lpAlgorithm": enum ( |
Fields | |
---|---|
timeLimit |
Maximum time a solver should spend on the problem (or infinite if not set). This value is not a hard limit, solve time may slightly exceed this value. This parameter is always passed to the underlying solver, the solver default is not used. A duration in seconds with up to nine fractional digits, ending with ' |
enableOutput |
Enables printing the solver implementation traces. The location of those traces depend on the solver. For SCIP and Gurobi this will be the standard output streams. For Glop and CP-SAT this will LOG(INFO). Note that if the solver supports message callback and the user registers a callback for it, then this parameter value is ignored and no traces are printed. |
lpAlgorithm |
The algorithm for solving a linear program. If LP_ALGORITHM_UNSPECIFIED, use the solver default algorithm. For problems that are not linear programs but where linear programming is a subroutine, solvers may use this value. E.g. MIP solvers will typically use this for the root LP solve only (and use dual simplex otherwise). |
presolve |
Effort on simplifying the problem before starting the main algorithm, or the solver default effort level if EMPHASIS_UNSPECIFIED. |
cuts |
Effort on getting a stronger LP relaxation (MIP only), or the solver default effort level if EMPHASIS_UNSPECIFIED. NOTE: disabling cuts may prevent callbacks from having a chance to add cuts at MIP_NODE, this behavior is solver specific. |
heuristics |
Effort in finding feasible solutions beyond those encountered in the complete search procedure (MIP only), or the solver default effort level if EMPHASIS_UNSPECIFIED. |
scaling |
Effort in rescaling the problem to improve numerical stability, or the solver default effort level if EMPHASIS_UNSPECIFIED. |
iterationLimit |
Limit on the iterations of the underlying algorithm (e.g. simplex pivots). The specific behavior is dependent on the solver and algorithm used, but often can give a deterministic solve limit (further configuration may be needed, e.g. one thread). Typically supported by LP, QP, and MIP solvers, but for MIP solvers see also nodeLimit. |
nodeLimit |
Limit on the number of subproblems solved in enumerative search (e.g. branch and bound). For many solvers this can be used to deterministically limit computation (further configuration may be needed, e.g. one thread). Typically for MIP solvers, see also iterationLimit. |
cutoffLimit |
The solver stops early if it can prove there are no primal solutions at least as good as cutoff. On an early stop, the solver returns termination reason NO_SOLUTION_FOUND and with limit CUTOFF and is not required to give any extra solution information. Has no effect on the return value if there is no early stop. It is recommended that you use a tolerance if you want solutions with objective exactly equal to cutoff to be returned. See the user guide for more details and a comparison with bestBoundLimit. |
objectiveLimit |
The solver stops early as soon as it finds a solution at least this good, with termination reason FEASIBLE and limit OBJECTIVE. |
bestBoundLimit |
The solver stops early as soon as it proves the best bound is at least this good, with termination reason FEASIBLE or NO_SOLUTION_FOUND and limit OBJECTIVE. See the user guide for more details and a comparison with cutoffLimit. |
solutionLimit |
The solver stops early after finding this many feasible solutions, with termination reason FEASIBLE and limit SOLUTION. Must be greater than zero if set. It is often used get the solver to stop on the first feasible solution found. Note that there is no guarantee on the objective value for any of the returned solutions. Solvers will typically not return more solutions than the solution limit, but this is not enforced by MathOpt, see also b/214041169. Currently supported for Gurobi and SCIP, and for CP-SAT only with value 1. |
threads |
If set, it must be >= 1. |
randomSeed |
Seed for the pseudo-random number generator in the underlying solver. Note that all solvers use pseudo-random numbers to select things such as perturbation in the LP algorithm, for tie-break-up rules, and for heuristic fixings. Varying this can have a noticeable impact on solver behavior. Although all solvers have a concept of seeds, note that valid values depend on the actual solver. - Gurobi: [0:GRB_MAXINT] (which as of Gurobi 9.0 is 2x10^9). - GSCIP: [0:2147483647] (which is MAX_INT or kint32max or 2^31-1). - GLOP: [0:2147483647] (same as above) In all cases, the solver will receive a value equal to: MAX(0, MIN(MAX_VALID_VALUE_FOR_SOLVER, randomSeed)). |
absoluteGapTolerance |
An absolute optimality tolerance (primarily) for MIP solvers. The absolute GAP is the absolute value of the difference between: * the objective value of the best feasible solution found, * the dual bound produced by the search. The solver can stop once the absolute GAP is at most absoluteGapTolerance (when set), and return TERMINATION_REASON_OPTIMAL. Must be >= 0 if set. See also relativeGapTolerance. |
relativeGapTolerance |
A relative optimality tolerance (primarily) for MIP solvers. The relative GAP is a normalized version of the absolute GAP (defined on absoluteGapTolerance), where the normalization is solver-dependent, e.g. the absolute GAP divided by the objective value of the best feasible solution found. The solver can stop once the relative GAP is at most relativeGapTolerance (when set), and return TERMINATION_REASON_OPTIMAL. Must be >= 0 if set. See also absoluteGapTolerance. |
solutionPoolSize |
Maintain up to |
LPAlgorithmProto
Selects an algorithm for solving linear programs.
Enums | |
---|---|
LP_ALGORITHM_UNSPECIFIED |
|
LP_ALGORITHM_PRIMAL_SIMPLEX |
The (primal) simplex method. Typically can provide primal and dual solutions, primal/dual rays on primal/dual unbounded problems, and a basis. |
LP_ALGORITHM_DUAL_SIMPLEX |
The dual simplex method. Typically can provide primal and dual solutions, primal/dual rays on primal/dual unbounded problems, and a basis. |
LP_ALGORITHM_BARRIER |
The barrier method, also commonly called an interior point method (IPM). Can typically give both primal and dual solutions. Some implementations can also produce rays on unbounded/infeasible problems. A basis is not given unless the underlying solver does "crossover" and finishes with simplex. |
LP_ALGORITHM_FIRST_ORDER |
An algorithm based around a first-order method. These will typically produce both primal and dual solutions, and potentially also certificates of primal and/or dual infeasibility. First-order methods typically will provide solutions with lower accuracy, so users should take care to set solution quality parameters (e.g., tolerances) and to validate solutions. |
EmphasisProto
Effort level applied to an optional task while solving (see SolveParametersProto for use).
Emphasis is used to configure a solver feature as follows: * If a solver doesn't support the feature, only UNSPECIFIED will always be valid, any other setting will typically an invalid argument error (some solvers may also accept OFF). * If the solver supports the feature: - When set to UNSPECIFIED, the underlying default is used. - When the feature cannot be turned off, OFF will return an error. - If the feature is enabled by default, the solver default is typically mapped to MEDIUM. - If the feature is supported, LOW, MEDIUM, HIGH, and VERY HIGH will never give an error, and will map onto their best match.
Enums | |
---|---|
EMPHASIS_UNSPECIFIED |
|
EMPHASIS_OFF |
|
EMPHASIS_LOW |
|
EMPHASIS_MEDIUM |
|
EMPHASIS_HIGH |
|
EMPHASIS_VERY_HIGH |
ModelSolveParametersProto
JSON representation |
---|
{ "variableValuesFilter": { object ( |
Fields | |
---|---|
variableValuesFilter |
Filter that is applied to all returned sparse containers keyed by variables in PrimalSolutionProto and PrimalRayProto (PrimalSolutionProto.variable_values, PrimalRayProto.variable_values). Requirements: * filteredIds are elements of VariablesProto.ids. |
dualValuesFilter |
Filter that is applied to all returned sparse containers keyed by linear constraints in DualSolutionProto and DualRay (DualSolutionProto.dual_values, DualRay.dual_values). Requirements: * filteredIds are elements of LinearConstraints.ids. |
reducedCostsFilter |
Filter that is applied to all returned sparse containers keyed by variables in DualSolutionProto and DualRay (DualSolutionProto.reduced_costs, DualRay.reduced_costs). Requirements: * filteredIds are elements of VariablesProto.ids. |
initialBasis |
Optional initial basis for warm starting simplex LP solvers. If set, it is expected to be valid according to |
solutionHints[] |
Optional solution hints. If the underlying solver only accepts a single hint, the first hint is used. |
branchingPriorities |
Optional branching priorities. Variables with higher values will be branched on first. Variables for which priorities are not set get the solver's default priority (usually zero). Requirements: * branchingPriorities.values must be finite. * branchingPriorities.ids must be elements of VariablesProto.ids. |
SparseVectorFilterProto
This message allows to query/set specific parts of a SparseXxxxVector. The default behavior is not to filter out anything. A common usage is to query only parts of solutions (only non-zero values, and/or just a hand-picked set of variable values).
JSON representation |
---|
{ "skipZeroValues": boolean, "filterByIds": boolean, "filteredIds": [ string ] } |
Fields | |
---|---|
skipZeroValues |
For SparseBoolVectorProto "zero" is |
filterByIds |
When true, return only the values corresponding to the IDs listed in filteredIds. |
filteredIds[] |
The list of IDs to use when filterByIds is true. Must be empty when filterByIds is false. NOTE: if this is empty, and filterByIds is true, you are saying that you do not want any information in the result. |
BasisProto
A combinatorial characterization for a solution to a linear program.
The simplex method for solving linear programs always returns a "basic feasible solution" which can be described combinatorially by a Basis. A basis assigns a BasisStatusProto for every variable and linear constraint.
E.g. consider a standard form LP: min c * x s.t. A * x = b x >= 0 that has more variables than constraints and with full row rank A.
Let n be the number of variables and m the number of linear constraints. A valid basis for this problem can be constructed as follows: * All constraints will have basis status FIXED. * Pick m variables such that the columns of A are linearly independent and assign the status BASIC. * Assign the status AT_LOWER for the remaining n - m variables.
The basic solution for this basis is the unique solution of A * x = b that has all variables with status AT_LOWER fixed to their lower bounds (all zero). The resulting solution is called a basic feasible solution if it also satisfies x >= 0.
JSON representation |
---|
{ "constraintStatus": { object ( |
Fields | |
---|---|
constraintStatus |
Constraint basis status. Requirements: * constraintStatus.ids is equal to LinearConstraints.ids. |
variableStatus |
Variable basis status. Requirements: * constraintStatus.ids is equal to VariablesProto.ids. |
basicDualFeasibility |
This is an advanced feature used by MathOpt to characterize feasibility of suboptimal LP solutions (optimal solutions will always have status SOLUTION_STATUS_FEASIBLE). For single-sided LPs it should be equal to the feasibility status of the associated dual solution. For two-sided LPs it may be different in some edge cases (e.g. incomplete solves with primal simplex). If you are providing a starting basis via ModelSolveParametersProto.initial_basis, this value is ignored. It is only relevant for the basis returned by SolutionProto.basis. |
SparseBasisStatusVector
A sparse representation of a vector of basis statuses.
JSON representation |
---|
{
"ids": [
string
],
"values": [
enum ( |
Fields | |
---|---|
ids[] |
Must be sorted (in increasing ordering) with all elements distinct. |
values[] |
Must have equal length to ids. |
BasisStatusProto
Status of a variable/constraint in a LP basis.
Enums | |
---|---|
BASIS_STATUS_UNSPECIFIED |
Guard value representing no status. |
BASIS_STATUS_FREE |
The variable/constraint is free (it has no finite bounds). |
BASIS_STATUS_AT_LOWER_BOUND |
The variable/constraint is at its lower bound (which must be finite). |
BASIS_STATUS_AT_UPPER_BOUND |
The variable/constraint is at its upper bound (which must be finite). |
BASIS_STATUS_FIXED_VALUE |
The variable/constraint has identical finite lower and upper bounds. |
BASIS_STATUS_BASIC |
The variable/constraint is basic. |
SolutionStatusProto
Feasibility of a primal or dual solution as claimed by the solver.
Enums | |
---|---|
SOLUTION_STATUS_UNSPECIFIED |
Guard value representing no status. |
SOLUTION_STATUS_UNDETERMINED |
Solver does not claim a feasibility status. |
SOLUTION_STATUS_FEASIBLE |
Solver claims the solution is feasible. |
SOLUTION_STATUS_INFEASIBLE |
Solver claims the solution is infeasible. |
SolutionHintProto
A suggested starting solution for the solver.
MIP solvers generally only want primal information (variableValues
), while LP solvers want both primal and dual information (dualValues
).
Many MIP solvers can work with: (1) partial solutions that do not specify all variables or (2) infeasible solutions. In these cases, solvers typically solve a sub-MIP to complete/correct the hint.
How the hint is used by the solver, if at all, is highly dependent on the solver, the problem type, and the algorithm used. The most reliable way to ensure your hint has an effect is to read the underlying solvers logs with and without the hint.
Simplex-based LP solvers typically prefer an initial basis to a solution hint (they need to crossover to convert the hint to a basic feasible solution otherwise).
JSON representation |
---|
{ "variableValues": { object ( |
Fields | |
---|---|
variableValues |
A possibly partial assignment of values to the primal variables of the problem. The solver-independent requirements for this sub-message are: * variableValues.ids are elements of VariablesProto.ids. * variableValues.values must all be finite. |
dualValues |
A (potentially partial) assignment of values to the linear constraints of the problem. Requirements: * dualValues.ids are elements of LinearConstraintsProto.ids. * dualValues.values must all be finite. |
SparseInt32VectorProto
A sparse representation of a vector of ints.
JSON representation |
---|
{ "ids": [ string ], "values": [ integer ] } |
Fields | |
---|---|
ids[] |
Should be sorted (in increasing ordering) with all elements distinct. |
values[] |
Must have equal length to ids. |
SolveResultProto
The contract of when primal/dual solutions/rays is complex, see termination_reasons.md for a complete description.
Until an exact contract is finalized, it is safest to simply check if a solution/ray is present rather than relying on the termination reason.
JSON representation |
---|
{ "termination": { object ( |
Fields | |
---|---|
termination |
The reason the solver stopped. |
solutions[] |
The general contract for the order of solutions that future solvers should implement is to order by: 1. The solutions with a primal feasible solution, ordered by best primal objective first. 2. The solutions with a dual feasible solution, ordered by best dual objective (unknown dual objective is worst) 3. All remaining solutions can be returned in any order. |
primalRays[] |
Directions of unbounded primal improvement, or equivalently, dual infeasibility certificates. Typically provided for TerminationReasonProtos UNBOUNDED and DUAL_INFEASIBLE |
dualRays[] |
Directions of unbounded dual improvement, or equivalently, primal infeasibility certificates. Typically provided for TerminationReasonProto INFEASIBLE. |
solveStats |
Statistics on the solve process, e.g. running time, iterations. |
TerminationProto
All information regarding why a call to Solve() terminated.
JSON representation |
---|
{ "reason": enum ( |
Fields | |
---|---|
reason |
Additional information in |
limit |
Is LIMIT_UNSPECIFIED unless reason is TERMINATION_REASON_FEASIBLE or TERMINATION_REASON_NO_SOLUTION_FOUND. Not all solvers can always determine the limit which caused termination, LIMIT_UNDETERMINED is used when the cause cannot be determined. |
detail |
Additional typically solver specific information about termination. |
problemStatus |
Feasibility statuses for primal and dual problems. As of July 18, 2023 this message may be missing. If missing, problemStatus can be found in SolveResultProto.solve_stats. |
objectiveBounds |
Bounds on the optimal objective value. As of July 18, 2023 this message may be missing. If missing, objectiveBounds.primal_bound can be found in SolveResultProto.solve.stats.best_primal_bound and objectiveBounds.dual_bound can be found in SolveResultProto.solve.stats.best_dual_bound |
TerminationReasonProto
The reason a call to Solve() terminates.
Enums | |
---|---|
TERMINATION_REASON_UNSPECIFIED |
|
TERMINATION_REASON_OPTIMAL |
A provably optimal solution (up to numerical tolerances) has been found. |
TERMINATION_REASON_INFEASIBLE |
The primal problem has no feasible solutions. |
TERMINATION_REASON_UNBOUNDED |
The primal problem is feasible and arbitrarily good solutions can be found along a primal ray. |
TERMINATION_REASON_INFEASIBLE_OR_UNBOUNDED |
The primal problem is either infeasible or unbounded. More details on the problem status may be available in solveStats.problem_status. Note that Gurobi's unbounded status may be mapped here. |
TERMINATION_REASON_IMPRECISE |
The problem was solved to one of the criteria above (Optimal, Infeasible, Unbounded, or InfeasibleOrUnbounded), but one or more tolerances was not met. Some primal/dual solutions/rays be present, but either they will be slightly infeasible, or (if the problem was nearly optimal) their may be a gap between the best solution objective and best objective bound. Users can still query primal/dual solutions/rays and solution stats, but they are responsible for dealing with the numerical imprecision. |
TERMINATION_REASON_FEASIBLE |
The optimizer reached some kind of limit and a primal feasible solution is returned. See SolveResultProto.limit_detail for detailed description of the kind of limit that was reached. |
TERMINATION_REASON_NO_SOLUTION_FOUND |
The optimizer reached some kind of limit and it did not find a primal feasible solution. See SolveResultProto.limit_detail for detailed description of the kind of limit that was reached. |
TERMINATION_REASON_NUMERICAL_ERROR |
The algorithm stopped because it encountered unrecoverable numerical error. No solution information is available. |
TERMINATION_REASON_OTHER_ERROR |
The algorithm stopped because of an error not covered by one of the statuses defined above. No solution information is available. |
LimitProto
When a Solve() stops early with TerminationReasonProto FEASIBLE or NO_SOLUTION_FOUND, the specific limit that was hit.
Enums | |
---|---|
LIMIT_UNSPECIFIED |
Used as a null value when we terminated not from a limit (e.g. TERMINATION_REASON_OPTIMAL). |
LIMIT_UNDETERMINED |
The underlying solver does not expose which limit was reached. |
LIMIT_ITERATION |
An iterative algorithm stopped after conducting the maximum number of iterations (e.g. simplex or barrier iterations). |
LIMIT_TIME |
The algorithm stopped after a user-specified computation time. |
LIMIT_NODE |
A branch-and-bound algorithm stopped because it explored a maximum number of nodes in the branch-and-bound tree. |
LIMIT_SOLUTION |
The algorithm stopped because it found the required number of solutions. This is often used in MIPs to get the solver to return the first feasible solution it encounters. |
LIMIT_MEMORY |
The algorithm stopped because it ran out of memory. |
LIMIT_CUTOFF |
The solver was run with a cutoff (e.g. SolveParameters.cutoff_limit was set) on the objective, indicating that the user did not want any solution worse than the cutoff, and the solver concluded there were no solutions at least as good as the cutoff. Typically no further solution information is provided. |
LIMIT_OBJECTIVE |
The algorithm stopped because it either found a solution or a bound better than a limit set by the user (see SolveParameters.objective_limit and SolveParameters.best_bound_limit). |
LIMIT_NORM |
The algorithm stopped because the norm of an iterate became too large. |
LIMIT_INTERRUPTED |
The algorithm stopped because of an interrupt signal or a user interrupt request. |
LIMIT_SLOW_PROGRESS |
The algorithm stopped because it was unable to continue making progress towards the solution. |
LIMIT_OTHER |
The algorithm stopped due to a limit not covered by one of the above. Note that LIMIT_UNDETERMINED is used when the reason cannot be determined, and LIMIT_OTHER is used when the reason is known but does not fit into any of the above alternatives. TerminationProto.detail may contain additional information about the limit. |
ProblemStatusProto
Feasibility status of the primal problem and its dual (or the dual of a continuous relaxation) as claimed by the solver. The solver is not required to return a certificate for the claim (e.g. the solver may claim primal feasibility without returning a primal feasible solutuion). This combined status gives a comprehensive description of a solver's claims about feasibility and unboundedness of the solved problem. For instance,
- a feasible status for primal and dual problems indicates the primal is feasible and bounded and likely has an optimal solution (guaranteed for problems without non-linear constraints).
- a primal feasible and a dual infeasible status indicates the primal problem is unbounded (i.e. has arbitrarily good solutions).
Note that a dual infeasible status by itself (i.e. accompanied by an undetermined primal status) does not imply the primal problem is unbounded as we could have both problems be infeasible. Also, while a primal and dual feasible status may imply the existence of an optimal solution, it does not guarantee the solver has actually found such optimal solution.
JSON representation |
---|
{ "primalStatus": enum ( |
Fields | |
---|---|
primalStatus |
Status for the primal problem. |
dualStatus |
Status for the dual problem (or for the dual of a continuous relaxation). |
primalOrDualInfeasible |
If true, the solver claims the primal or dual problem is infeasible, but it does not know which (or if both are infeasible). Can be true only when primal_problem_status = dual_problem_status = kUndetermined. This extra information is often needed when preprocessing determines there is no optimal solution to the problem (but can't determine if it is due to infeasibility, unboundedness, or both). |
FeasibilityStatusProto
Problem feasibility status as claimed by the solver (solver is not required to return a certificate for the claim).
Enums | |
---|---|
FEASIBILITY_STATUS_UNSPECIFIED |
Guard value representing no status. |
FEASIBILITY_STATUS_UNDETERMINED |
Solver does not claim a status. |
FEASIBILITY_STATUS_FEASIBLE |
Solver claims the problem is feasible. |
FEASIBILITY_STATUS_INFEASIBLE |
Solver claims the problem is infeasible. |
ObjectiveBoundsProto
Bounds on the optimal objective value.
JSON representation |
---|
{ "primalBound": number, "dualBound": number } |
Fields | |
---|---|
primalBound |
Solver claims the optimal value is equal or better (smaller for minimization and larger for maximization) than primalBound up to the solvers primal feasibility tolerance (see warning below): * primalBound is trivial (+inf for minimization and -inf maximization) when the solver does not claim to have such bound. * primalBound can be closer to the optimal value than the objective of the best primal feasible solution. In particular, primalBound may be non-trivial even when no primal feasible solutions are returned. Warning: The precise claim is that there exists a primal solution that: * is numerically feasible (i.e. feasible up to the solvers tolerance), and * has an objective value primalBound. This numerically feasible solution could be slightly infeasible, in which case primalBound could be strictly better than the optimal value. Translating a primal feasibility tolerance to a tolerance on primalBound is non-trivial, specially when the feasibility tolerance is relatively large (e.g. when solving with PDLP). |
dualBound |
Solver claims the optimal value is equal or worse (larger for minimization and smaller for maximization) than dualBound up to the solvers dual feasibility tolerance (see warning below): * dualBound is trivial (-inf for minimization and +inf maximization) when the solver does not claim to have such bound. Similarly to primalBound, this may happen for some solvers even when returning optimal. MIP solvers will typically report a bound even if it is imprecise. * for continuous problems dualBound can be closer to the optimal value than the objective of the best dual feasible solution. For MIP one of the first non-trivial values for dualBound is often the optimal value of the LP relaxation of the MIP. * dualBound should be better (smaller for minimization and larger for maximization) than primalBound up to the solvers tolerances (see warning below). Warning: * For continuous problems, the precise claim is that there exists a dual solution that: * is numerically feasible (i.e. feasible up to the solvers tolerance), and * has an objective value dualBound. This numerically feasible solution could be slightly infeasible, in which case dualBound could be strictly worse than the optimal value and primalBound. Similar to the primal case, translating a dual feasibility tolerance to a tolerance on dualBound is non-trivial, specially when the feasibility tolerance is relatively large. However, some solvers provide a corrected version of dualBound that can be numerically safer. This corrected version can be accessed through the solver's specific output (e.g. for PDLP, pdlp_output.convergence_information.corrected_dual_objective). * For MIP solvers, dualBound may be associated to a dual solution for some continuous relaxation (e.g. LP relaxation), but it is often a complex consequence of the solvers execution and is typically more imprecise than the bounds reported by LP solvers. |
SolutionProto
What is included in a solution depends on the kind of problem and solver. The current common patterns are 1. MIP solvers return only a primal solution. 2. Simplex LP solvers often return a basis and the primal and dual solutions associated to this basis. 3. Other continuous solvers often return a primal and dual solution solution that are connected in a solver-dependent form.
Requirements: * at least one field must be set; a solution can't be empty.
JSON representation |
---|
{ "primalSolution": { object ( |
Fields | |
---|---|
primalSolution |
|
dualSolution |
|
basis |
|
PrimalSolutionProto
A solution to an optimization problem.
E.g. consider a simple linear program: min c * x s.t. A * x >= b x >= 0. A primal solution is assignment values to x. It is feasible if it satisfies A * x >= b and x >= 0 from above. In the message PrimalSolutionProto below, variableValues is x and objectiveValue is c * x.
JSON representation |
---|
{ "variableValues": { object ( |
Fields | |
---|---|
variableValues |
Requirements: * variableValues.ids are elements of VariablesProto.ids. * variableValues.values must all be finite. |
objectiveValue |
Objective value as computed by the underlying solver. Cannot be infinite or NaN. |
auxiliaryObjectiveValues |
Auxiliary objective values as computed by the underlying solver. Keys must be valid auxiliary objective IDs. Values cannot be infinite or NaN. An object containing a list of |
feasibilityStatus |
Feasibility status of the solution according to the underlying solver. |
DualSolutionProto
A solution to the dual of an optimization problem.
E.g. consider the primal dual pair linear program pair: (Primal) (Dual) min c * x max b * y s.t. A * x >= b s.t. y * A + r = c x >= 0 y, r >= 0. The dual solution is the pair (y, r). It is feasible if it satisfies the constraints from (Dual) above.
In the message below, y is dualValues, r is reducedCosts, and b * y is objective value.
JSON representation |
---|
{ "dualValues": { object ( |
Fields | |
---|---|
dualValues |
Requirements: * dualValues.ids are elements of LinearConstraints.ids. * dualValues.values must all be finite. |
reducedCosts |
Requirements: * reducedCosts.ids are elements of VariablesProto.ids. * reducedCosts.values must all be finite. |
feasibilityStatus |
Feasibility status of the solution according to the underlying solver. |
objectiveValue |
|
PrimalRayProto
A direction of unbounded improvement to an optimization problem; equivalently, a certificate of infeasibility for the dual of the optimization problem.
E.g. consider a simple linear program: min c * x s.t. A * x >= b x >= 0 A primal ray is an x that satisfies: c * x < 0 A * x >= 0 x >= 0 Observe that given a feasible solution, any positive multiple of the primal ray plus that solution is still feasible, and gives a better objective value. A primal ray also proves the dual optimization problem infeasible.
In the message PrimalRay below, variableValues is x.
JSON representation |
---|
{
"variableValues": {
object ( |
Fields | |
---|---|
variableValues |
Requirements: * variableValues.ids are elements of VariablesProto.ids. * variableValues.values must all be finite. |
DualRayProto
A direction of unbounded improvement to the dual of an optimization, problem; equivalently, a certificate of primal infeasibility.
E.g. consider the primal dual pair linear program pair: (Primal) (Dual) min c * x max b * y s.t. A * x >= b s.t. y * A + r = c x >= 0 y, r >= 0. The dual ray is the pair (y, r) satisfying: b * y > 0 y * A + r = 0 y, r >= 0 Observe that adding a positive multiple of (y, r) to dual feasible solution maintains dual feasibility and improves the objective (proving the dual is unbounded). The dual ray also proves the primal problem is infeasible.
In the message DualRay below, y is dualValues and r is reducedCosts.
JSON representation |
---|
{ "dualValues": { object ( |
Fields | |
---|---|
dualValues |
Requirements: * dualValues.ids are elements of LinearConstraints.ids. * dualValues.values must all be finite. |
reducedCosts |
Requirements: * reducedCosts.ids are elements of VariablesProto.ids. * reducedCosts.values must all be finite. |
SolveStatsProto
JSON representation |
---|
{
"solveTime": string,
"problemStatus": {
object ( |
Fields | |
---|---|
solveTime |
Elapsed wall clock time as measured by math_opt, roughly the time inside Solver::Solve(). Note: this does not include work done building the model. A duration in seconds with up to nine fractional digits, ending with ' |
problemStatus |
Feasibility statuses for primal and dual problems. |
simplexIterations |
|
barrierIterations |
|
firstOrderIterations |
|
nodeCount |
|