Method: mathopt.solveMathOptModel

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 (SolverTypeProto),
  "model": {
    object (ModelProto)
  },
  "parameters": {
    object (SolveParametersProto)
  },
  "modelParameters": {
    object (ModelSolveParametersProto)
  }
}
Fields
solverType

enum (SolverTypeProto)

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

object (ModelProto)

Required. A mathematical representation of the optimization problem to solve.

parameters

object (SolveParametersProto)

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

object (ModelSolveParametersProto)

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 (SolveResultProto)
  },
  "messages": [
    string
  ]
}
Fields
result

object (SolveResultProto)

Description of the output of solving the model in the request.

messages[]

string

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 (VariablesProto)
  },
  "objective": {
    object (ObjectiveProto)
  },
  "auxiliaryObjectives": {
    string: {
      object (ObjectiveProto)
    },
    ...
  },
  "linearConstraints": {
    object (LinearConstraintsProto)
  },
  "linearConstraintMatrix": {
    object (SparseDoubleMatrixProto)
  },
  "quadraticConstraints": {
    string: {
      object (QuadraticConstraintProto)
    },
    ...
  },
  "secondOrderConeConstraints": {
    string: {
      object (SecondOrderConeConstraintProto)
    },
    ...
  },
  "sos1Constraints": {
    string: {
      object (SosConstraintProto)
    },
    ...
  },
  "sos2Constraints": {
    string: {
      object (SosConstraintProto)
    },
    ...
  },
  "indicatorConstraints": {
    string: {
      object (IndicatorConstraintProto)
    },
    ...
  }
}
Fields
name

string

variables

object (VariablesProto)

objective

object (ObjectiveProto)

The primary objective in the model.

auxiliaryObjectives

map (key: string (int64 format), value: object (ObjectiveProto))

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 objective.

An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

linearConstraints

object (LinearConstraintsProto)

linearConstraintMatrix

object (SparseDoubleMatrixProto)

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

map (key: string (int64 format), value: object (QuadraticConstraintProto))

Quadratic constraints in the model.

An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

secondOrderConeConstraints

map (key: string (int64 format), value: object (SecondOrderConeConstraintProto))

Second-order cone constraints in the model.

An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

sos1Constraints

map (key: string (int64 format), value: object (SosConstraintProto))

SOS1 constraints in the model, which constrain that at most one expression can be nonzero. The optional weights entries are an implementation detail used by the solver to (hopefully) converge more quickly. In more detail, solvers may (or may not) use these weights to select branching decisions that produce "balanced" children nodes.

An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

sos2Constraints

map (key: string (int64 format), value: object (SosConstraintProto))

SOS2 constraints in the model, which constrain that at most two entries of expression can be nonzero, and they must be adjacent in their ordering. If no weights are provided, this ordering is their linear ordering in the expressions list; if weights are presented, the ordering is taken with respect to these values in increasing order.

An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

indicatorConstraints

map (key: string (int64 format), value: object (IndicatorConstraintProto))

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 "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

VariablesProto

As used below, we define "#variables" = size(VariablesProto.ids).

JSON representation
{
  "ids": [
    string
  ],
  "lowerBounds": [
    number
  ],
  "upperBounds": [
    number
  ],
  "integers": [
    boolean
  ],
  "names": [
    string
  ]
}
Fields
ids[]

string (int64 format)

Must be nonnegative and strictly increasing. The max(int64) value can't be used.

lowerBounds[]

number

Should have length equal to #variables, values in [-inf, inf).

upperBounds[]

number

Should have length equal to #variables, values in (-inf, inf].

integers[]

boolean

Should have length equal to #variables. Value is false for continuous variables and true for integer variables.

names[]

string

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 (SparseDoubleVectorProto)
  },
  "quadraticCoefficients": {
    object (SparseDoubleMatrixProto)
  },
  "name": string,
  "priority": string
}
Fields
maximize

boolean

false is minimize, true is maximize

offset

number

Must be finite and not NaN.

linearCoefficients

object (SparseDoubleVectorProto)

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

object (SparseDoubleMatrixProto)

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

string

Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.objectives and AuxiliaryObjectivesUpdatesProto.new_objectives.

priority

string (int64 format)

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[]

string (int64 format)

Must be sorted (in increasing ordering) with all elements distinct.

values[]

number

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[]

string (int64 format)

columnIds[]

string (int64 format)

coefficients[]

number

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[]

string (int64 format)

Must be nonnegative and strictly increasing. The max(int64) value can't be used.

lowerBounds[]

number

Should have length equal to #linear constraints, values in [-inf, inf).

upperBounds[]

number

Should have length equal to #linear constraints, values in (-inf, inf].

names[]

string

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 (SparseDoubleVectorProto)
  },
  "quadraticTerms": {
    object (SparseDoubleMatrixProto)
  },
  "lowerBound": number,
  "upperBound": number,
  "name": string
}
Fields
linearTerms

object (SparseDoubleVectorProto)

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

object (SparseDoubleMatrixProto)

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

number

Must have value in [-inf, inf), and be less than or equal to upperBound.

upperBound

number

Must have value in (-inf, inf], and be greater than or equal to lowerBound.

name

string

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 (LinearExpressionProto)
  },
  "argumentsToNorm": [
    {
      object (LinearExpressionProto)
    }
  ],
  "name": string
}
Fields
upperBound

object (LinearExpressionProto)

argumentsToNorm[]

object (LinearExpressionProto)

name

string

Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.second_order_cone_constraints and SecondOrderConeConstraintUpdatesProto.new_constraints.

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[]

string (int64 format)

Ids of variables. Must be sorted (in increasing ordering) with all elements distinct.

coefficients[]

number

Must have equal length to ids. Values must be finite may not be NaN.

offset

number

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 (LinearExpressionProto)
    }
  ],
  "weights": [
    number
  ],
  "name": string
}
Fields
expressions[]

object (LinearExpressionProto)

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[]

number

Either empty or of equal length to expressions. If empty, default weights are 1, 2, ... If present, the entries must be unique.

name

string

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 (SparseDoubleVectorProto)
  },
  "lowerBound": number,
  "upperBound": number,
  "name": string,
  "indicatorId": string
}
Fields
activateOnZero

boolean

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

object (SparseDoubleVectorProto)

Must be a valid linear expression with respect to the containing model: * All stated conditions on SparseDoubleVectorProto, * All elements of expression.values must be finite, * expression.ids are a subset of VariablesProto.ids.

lowerBound

number

Must have value in [-inf, inf); cannot be NaN.

upperBound

number

Must have value in (-inf, inf]; cannot be NaN.

name

string

Parent messages may have uniqueness requirements on this field; e.g., see ModelProto.indicator_constraints and IndicatorConstraintUpdatesProto.new_constraints.

indicatorId

string (int64 format)

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 (LPAlgorithmProto),
  "presolve": enum (EmphasisProto),
  "cuts": enum (EmphasisProto),
  "heuristics": enum (EmphasisProto),
  "scaling": enum (EmphasisProto),
  "iterationLimit": string,
  "nodeLimit": string,
  "cutoffLimit": number,
  "objectiveLimit": number,
  "bestBoundLimit": number,
  "solutionLimit": integer,
  "threads": integer,
  "randomSeed": integer,
  "absoluteGapTolerance": number,
  "relativeGapTolerance": number,
  "solutionPoolSize": integer
}
Fields
timeLimit

string (Duration format)

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 's'. Example: "3.5s".

enableOutput

boolean

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

enum (LPAlgorithmProto)

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

enum (EmphasisProto)

Effort on simplifying the problem before starting the main algorithm, or the solver default effort level if EMPHASIS_UNSPECIFIED.

cuts

enum (EmphasisProto)

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

enum (EmphasisProto)

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

enum (EmphasisProto)

Effort in rescaling the problem to improve numerical stability, or the solver default effort level if EMPHASIS_UNSPECIFIED.

iterationLimit

string (int64 format)

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

string (int64 format)

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

number

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

number

The solver stops early as soon as it finds a solution at least this good, with termination reason FEASIBLE and limit OBJECTIVE.

bestBoundLimit

number

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

integer

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

integer

If set, it must be >= 1.

randomSeed

integer

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

number

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

number

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

integer

Maintain up to solutionPoolSize solutions while searching. The solution pool generally has two functions: (1) For solvers that can return more than one solution, this limits how many solutions will be returned. (2) Some solvers may run heuristics using solutions from the solution pool, so changing this value may affect the algorithm's path. To force the solver to fill the solution pool, e.g. with the n best solutions, requires further, solver specific configuration.

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 (SparseVectorFilterProto)
  },
  "dualValuesFilter": {
    object (SparseVectorFilterProto)
  },
  "reducedCostsFilter": {
    object (SparseVectorFilterProto)
  },
  "initialBasis": {
    object (BasisProto)
  },
  "solutionHints": [
    {
      object (SolutionHintProto)
    }
  ],
  "branchingPriorities": {
    object (SparseInt32VectorProto)
  }
}
Fields
variableValuesFilter

object (SparseVectorFilterProto)

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

object (SparseVectorFilterProto)

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

object (SparseVectorFilterProto)

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

object (BasisProto)

Optional initial basis for warm starting simplex LP solvers. If set, it is expected to be valid according to ValidateBasis in validators/solution_validator.h for the current ModelSummary.

solutionHints[]

object (SolutionHintProto)

Optional solution hints. If the underlying solver only accepts a single hint, the first hint is used.

branchingPriorities

object (SparseInt32VectorProto)

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

boolean

For SparseBoolVectorProto "zero" is false.

filterByIds

boolean

When true, return only the values corresponding to the IDs listed in filteredIds.

filteredIds[]

string (int64 format)

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 (SparseBasisStatusVector)
  },
  "variableStatus": {
    object (SparseBasisStatusVector)
  },
  "basicDualFeasibility": enum (SolutionStatusProto)
}
Fields
constraintStatus

object (SparseBasisStatusVector)

Constraint basis status.

Requirements: * constraintStatus.ids is equal to LinearConstraints.ids.

variableStatus

object (SparseBasisStatusVector)

Variable basis status.

Requirements: * constraintStatus.ids is equal to VariablesProto.ids.

basicDualFeasibility

enum (SolutionStatusProto)

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 (BasisStatusProto)
  ]
}
Fields
ids[]

string (int64 format)

Must be sorted (in increasing ordering) with all elements distinct.

values[]

enum (BasisStatusProto)

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 (SparseDoubleVectorProto)
  },
  "dualValues": {
    object (SparseDoubleVectorProto)
  }
}
Fields
variableValues

object (SparseDoubleVectorProto)

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

object (SparseDoubleVectorProto)

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[]

string (int64 format)

Should be sorted (in increasing ordering) with all elements distinct.

values[]

integer

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 (TerminationProto)
  },
  "solutions": [
    {
      object (SolutionProto)
    }
  ],
  "primalRays": [
    {
      object (PrimalRayProto)
    }
  ],
  "dualRays": [
    {
      object (DualRayProto)
    }
  ],
  "solveStats": {
    object (SolveStatsProto)
  }
}
Fields
termination

object (TerminationProto)

The reason the solver stopped.

solutions[]

object (SolutionProto)

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[]

object (PrimalRayProto)

Directions of unbounded primal improvement, or equivalently, dual infeasibility certificates. Typically provided for TerminationReasonProtos UNBOUNDED and DUAL_INFEASIBLE

dualRays[]

object (DualRayProto)

Directions of unbounded dual improvement, or equivalently, primal infeasibility certificates. Typically provided for TerminationReasonProto INFEASIBLE.

solveStats

object (SolveStatsProto)

Statistics on the solve process, e.g. running time, iterations.

TerminationProto

All information regarding why a call to Solve() terminated.

JSON representation
{
  "reason": enum (TerminationReasonProto),
  "limit": enum (LimitProto),
  "detail": string,
  "problemStatus": {
    object (ProblemStatusProto)
  },
  "objectiveBounds": {
    object (ObjectiveBoundsProto)
  }
}
Fields
reason

enum (TerminationReasonProto)

Additional information in limit when value is TERMINATION_REASON_FEASIBLE or TERMINATION_REASON_NO_SOLUTION_FOUND, see limit for details.

limit

enum (LimitProto)

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

string

Additional typically solver specific information about termination.

problemStatus

object (ProblemStatusProto)

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

object (ObjectiveBoundsProto)

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 (FeasibilityStatusProto),
  "dualStatus": enum (FeasibilityStatusProto),
  "primalOrDualInfeasible": boolean
}
Fields
primalStatus

enum (FeasibilityStatusProto)

Status for the primal problem.

dualStatus

enum (FeasibilityStatusProto)

Status for the dual problem (or for the dual of a continuous relaxation).

primalOrDualInfeasible

boolean

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

number

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

number

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 (PrimalSolutionProto)
  },
  "dualSolution": {
    object (DualSolutionProto)
  },
  "basis": {
    object (BasisProto)
  }
}
Fields
primalSolution

object (PrimalSolutionProto)

dualSolution

object (DualSolutionProto)

basis

object (BasisProto)

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 (SparseDoubleVectorProto)
  },
  "objectiveValue": number,
  "auxiliaryObjectiveValues": {
    string: number,
    ...
  },
  "feasibilityStatus": enum (SolutionStatusProto)
}
Fields
variableValues

object (SparseDoubleVectorProto)

Requirements: * variableValues.ids are elements of VariablesProto.ids. * variableValues.values must all be finite.

objectiveValue

number

Objective value as computed by the underlying solver. Cannot be infinite or NaN.

auxiliaryObjectiveValues

map (key: string (int64 format), value: number)

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 "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.

feasibilityStatus

enum (SolutionStatusProto)

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 (SparseDoubleVectorProto)
  },
  "reducedCosts": {
    object (SparseDoubleVectorProto)
  },
  "feasibilityStatus": enum (SolutionStatusProto),
  "objectiveValue": number
}
Fields
dualValues

object (SparseDoubleVectorProto)

Requirements: * dualValues.ids are elements of LinearConstraints.ids. * dualValues.values must all be finite.

reducedCosts

object (SparseDoubleVectorProto)

Requirements: * reducedCosts.ids are elements of VariablesProto.ids. * reducedCosts.values must all be finite.

feasibilityStatus

enum (SolutionStatusProto)

Feasibility status of the solution according to the underlying solver.

objectiveValue

number

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 (SparseDoubleVectorProto)
  }
}
Fields
variableValues

object (SparseDoubleVectorProto)

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 (SparseDoubleVectorProto)
  },
  "reducedCosts": {
    object (SparseDoubleVectorProto)
  }
}
Fields
dualValues

object (SparseDoubleVectorProto)

Requirements: * dualValues.ids are elements of LinearConstraints.ids. * dualValues.values must all be finite.

reducedCosts

object (SparseDoubleVectorProto)

Requirements: * reducedCosts.ids are elements of VariablesProto.ids. * reducedCosts.values must all be finite.

SolveStatsProto

JSON representation
{
  "solveTime": string,
  "problemStatus": {
    object (ProblemStatusProto)
  },
  "simplexIterations": string,
  "barrierIterations": string,
  "firstOrderIterations": string,
  "nodeCount": string
}
Fields
solveTime

string (Duration format)

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 's'. Example: "3.5s".

problemStatus

object (ProblemStatusProto)

Feasibility statuses for primal and dual problems.

simplexIterations

string (int64 format)

barrierIterations

string (int64 format)

firstOrderIterations

string (int64 format)

nodeCount

string (int64 format)