ortools.math_opt.python.parameters

Configures the solving of an optimization model.

  1#!/usr/bin/env python3
  2# Copyright 2010-2025 Google LLC
  3# Licensed under the Apache License, Version 2.0 (the "License");
  4# you may not use this file except in compliance with the License.
  5# You may obtain a copy of the License at
  6#
  7#     http://www.apache.org/licenses/LICENSE-2.0
  8#
  9# Unless required by applicable law or agreed to in writing, software
 10# distributed under the License is distributed on an "AS IS" BASIS,
 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12# See the License for the specific language governing permissions and
 13# limitations under the License.
 14
 15"""Configures the solving of an optimization model."""
 16
 17import dataclasses
 18import datetime
 19import enum
 20from typing import Dict, Optional
 21
 22from ortools.pdlp import solvers_pb2 as pdlp_solvers_pb2
 23from ortools.glop import parameters_pb2 as glop_parameters_pb2
 24from ortools.math_opt import parameters_pb2 as math_opt_parameters_pb2
 25from ortools.math_opt.solvers import glpk_pb2
 26from ortools.math_opt.solvers import gurobi_pb2
 27from ortools.math_opt.solvers import highs_pb2
 28from ortools.math_opt.solvers import osqp_pb2
 29from ortools.math_opt.solvers.gscip import gscip_pb2
 30from ortools.sat import sat_parameters_pb2
 31
 32
 33@enum.unique
 34class SolverType(enum.Enum):
 35    """The underlying solver to use.
 36
 37    This must stay synchronized with math_opt_parameters_pb2.SolverTypeProto.
 38
 39    Attributes:
 40      GSCIP: Solving Constraint Integer Programs (SCIP) solver (third party).
 41        Supports LP, MIP, and nonconvex integer quadratic problems. No dual data
 42        for LPs is returned though. Prefer GLOP for LPs.
 43      GUROBI: Gurobi solver (third party). Supports LP, MIP, and nonconvex integer
 44        quadratic problems. Generally the fastest option, but has special
 45        licensing, see go/gurobi-google for details.
 46      GLOP: Google's Glop linear solver. Supports LP with primal and dual simplex
 47        methods.
 48      CP_SAT: Google's CP-SAT solver. Supports problems where all variables are
 49        integer and bounded (or implied to be after presolve). Experimental
 50        support to rescale and discretize problems with continuous variables.
 51      MOE:begin_intracomment_strip
 52      PDLP: Google's PDLP solver. Supports LP and convex diagonal quadratic
 53        objectives. Uses first order methods rather than simplex. Can solve very
 54        large problems.
 55      MOE:end_intracomment_strip
 56      GLPK: GNU Linear Programming Kit (GLPK) (third party). Supports MIP and LP.
 57        Thread-safety: GLPK use thread-local storage for memory allocations. As a
 58        consequence when using IncrementalSolver, the user must make sure that
 59        instances are closed on the same thread as they are created or GLPK will
 60        crash. To do so, use `with` or call IncrementalSolver#close(). It seems OK
 61        to call IncrementalSolver#Solve() from another thread than the one used to
 62        create the Solver but it is not documented by GLPK and should be avoided.
 63        Of course these limitations do not apply to the solve() function that
 64        recreates a new GLPK problem in the calling thread and destroys before
 65        returning.  When solving a LP with the presolver, a solution (and the
 66        unbound rays) are only returned if an optimal solution has been found.
 67        Else nothing is returned. See glpk-5.0/doc/glpk.pdf page #40 available
 68        from glpk-5.0.tar.gz for details.
 69      OSQP: The Operator Splitting Quadratic Program (OSQP) solver (third party).
 70        Supports continuous problems with linear constraints and linear or convex
 71        quadratic objectives. Uses a first-order method.
 72      ECOS: The Embedded Conic Solver (ECOS) (third party). Supports LP and SOCP
 73        problems. Uses interior point methods (barrier).
 74      SCS: The Splitting Conic Solver (SCS) (third party). Supports LP and SOCP
 75        problems. Uses a first-order method.
 76      HIGHS: The HiGHS Solver (third party). Supports LP and MIP problems (convex
 77        QPs are unimplemented).
 78      SANTORINI: The Santorini Solver (first party). Supports MIP. Experimental,
 79        do not use in production.
 80    """
 81
 82    GSCIP = math_opt_parameters_pb2.SOLVER_TYPE_GSCIP
 83    GUROBI = math_opt_parameters_pb2.SOLVER_TYPE_GUROBI
 84    GLOP = math_opt_parameters_pb2.SOLVER_TYPE_GLOP
 85    CP_SAT = math_opt_parameters_pb2.SOLVER_TYPE_CP_SAT
 86    PDLP = math_opt_parameters_pb2.SOLVER_TYPE_PDLP
 87    GLPK = math_opt_parameters_pb2.SOLVER_TYPE_GLPK
 88    OSQP = math_opt_parameters_pb2.SOLVER_TYPE_OSQP
 89    ECOS = math_opt_parameters_pb2.SOLVER_TYPE_ECOS
 90    SCS = math_opt_parameters_pb2.SOLVER_TYPE_SCS
 91    HIGHS = math_opt_parameters_pb2.SOLVER_TYPE_HIGHS
 92    SANTORINI = math_opt_parameters_pb2.SOLVER_TYPE_SANTORINI
 93
 94
 95def solver_type_from_proto(
 96    proto_value: math_opt_parameters_pb2.SolverTypeProto,
 97) -> Optional[SolverType]:
 98    if proto_value == math_opt_parameters_pb2.SOLVER_TYPE_UNSPECIFIED:
 99        return None
100    return SolverType(proto_value)
101
102
103def solver_type_to_proto(
104    solver_type: Optional[SolverType],
105) -> math_opt_parameters_pb2.SolverTypeProto:
106    if solver_type is None:
107        return math_opt_parameters_pb2.SOLVER_TYPE_UNSPECIFIED
108    return solver_type.value
109
110
111@enum.unique
112class LPAlgorithm(enum.Enum):
113    """Selects an algorithm for solving linear programs.
114
115    Attributes:
116      * UNPSECIFIED: No algorithm is selected.
117      * PRIMAL_SIMPLEX: The (primal) simplex method. Typically can provide primal
118        and dual solutions, primal/dual rays on primal/dual unbounded problems,
119        and a basis.
120      * DUAL_SIMPLEX: The dual simplex method. Typically can provide primal and
121        dual solutions, primal/dual rays on primal/dual unbounded problems, and a
122        basis.
123      * BARRIER: The barrier method, also commonly called an interior point method
124        (IPM). Can typically give both primal and dual solutions. Some
125        implementations can also produce rays on unbounded/infeasible problems. A
126        basis is not given unless the underlying solver does "crossover" and
127        finishes with simplex.
128      * FIRST_ORDER: An algorithm based around a first-order method. These will
129        typically produce both primal and dual solutions, and potentially also
130        certificates of primal and/or dual infeasibility. First-order methods
131        typically will provide solutions with lower accuracy, so users should take
132        care to set solution quality parameters (e.g., tolerances) and to validate
133        solutions.
134
135    This must stay synchronized with math_opt_parameters_pb2.LPAlgorithmProto.
136    """
137
138    PRIMAL_SIMPLEX = math_opt_parameters_pb2.LP_ALGORITHM_PRIMAL_SIMPLEX
139    DUAL_SIMPLEX = math_opt_parameters_pb2.LP_ALGORITHM_DUAL_SIMPLEX
140    BARRIER = math_opt_parameters_pb2.LP_ALGORITHM_BARRIER
141    FIRST_ORDER = math_opt_parameters_pb2.LP_ALGORITHM_FIRST_ORDER
142
143
144def lp_algorithm_from_proto(
145    proto_value: math_opt_parameters_pb2.LPAlgorithmProto,
146) -> Optional[LPAlgorithm]:
147    if proto_value == math_opt_parameters_pb2.LP_ALGORITHM_UNSPECIFIED:
148        return None
149    return LPAlgorithm(proto_value)
150
151
152def lp_algorithm_to_proto(
153    lp_algorithm: Optional[LPAlgorithm],
154) -> math_opt_parameters_pb2.LPAlgorithmProto:
155    if lp_algorithm is None:
156        return math_opt_parameters_pb2.LP_ALGORITHM_UNSPECIFIED
157    return lp_algorithm.value
158
159
160@enum.unique
161class Emphasis(enum.Enum):
162    """Effort level applied to an optional task while solving (see SolveParameters for use).
163
164    - OFF: disable this task.
165    - LOW: apply reduced effort.
166    - MEDIUM: typically the default setting (unless the default is off).
167    - HIGH: apply extra effort beyond MEDIUM.
168    - VERY_HIGH: apply the maximum effort.
169
170    Typically used as Optional[Emphasis]. It used to configure a solver feature as
171    follows:
172      * If a solver doesn't support the feature, only None will always be valid,
173        any other setting will give an invalid argument error (some solvers may
174        also accept OFF).
175      * If the solver supports the feature:
176        - When set to None, the underlying default is used.
177        - When the feature cannot be turned off, OFF will produce an error.
178        - If the feature is enabled by default, the solver default is typically
179          mapped to MEDIUM.
180        - If the feature is supported, LOW, MEDIUM, HIGH, and VERY HIGH will never
181          give an error, and will map onto their best match.
182
183    This must stay synchronized with math_opt_parameters_pb2.EmphasisProto.
184    """
185
186    OFF = math_opt_parameters_pb2.EMPHASIS_OFF
187    LOW = math_opt_parameters_pb2.EMPHASIS_LOW
188    MEDIUM = math_opt_parameters_pb2.EMPHASIS_MEDIUM
189    HIGH = math_opt_parameters_pb2.EMPHASIS_HIGH
190    VERY_HIGH = math_opt_parameters_pb2.EMPHASIS_VERY_HIGH
191
192
193def emphasis_from_proto(
194    proto_value: math_opt_parameters_pb2.EmphasisProto,
195) -> Optional[Emphasis]:
196    if proto_value == math_opt_parameters_pb2.EMPHASIS_UNSPECIFIED:
197        return None
198    return Emphasis(proto_value)
199
200
201def emphasis_to_proto(
202    emphasis: Optional[Emphasis],
203) -> math_opt_parameters_pb2.EmphasisProto:
204    if emphasis is None:
205        return math_opt_parameters_pb2.EMPHASIS_UNSPECIFIED
206    return emphasis.value
207
208
209@dataclasses.dataclass
210class GurobiParameters:
211    """Gurobi specific parameters for solving.
212
213    See https://www.gurobi.com/documentation/9.1/refman/parameters.html for a list
214    of possible parameters.
215
216    Example use:
217      gurobi=GurobiParameters();
218      gurobi.param_values["BarIterLimit"] = "10";
219
220    With Gurobi, the order that parameters are applied can have an impact in rare
221    situations. Parameters are applied in the following order:
222     * LogToConsole is set from SolveParameters.enable_output.
223     * Any common parameters not overwritten by GurobiParameters.
224     * param_values in iteration order (insertion order).
225    We set LogToConsole first because setting other parameters can generate
226    output.
227    """
228
229    param_values: Dict[str, str] = dataclasses.field(default_factory=dict)
230
231    def to_proto(self) -> gurobi_pb2.GurobiParametersProto:
232        return gurobi_pb2.GurobiParametersProto(
233            parameters=[
234                gurobi_pb2.GurobiParametersProto.Parameter(name=key, value=val)
235                for key, val in self.param_values.items()
236            ]
237        )
238
239
240@dataclasses.dataclass
241class GlpkParameters:
242    """GLPK specific parameters for solving.
243
244    Fields are optional to enable to capture user intention; if they set
245    explicitly a value to then no generic solve parameters will overwrite this
246    parameter. User specified solver specific parameters have priority on generic
247    parameters.
248
249    Attributes:
250      compute_unbound_rays_if_possible: Compute the primal or dual unbound ray
251        when the variable (structural or auxiliary) causing the unboundness is
252        identified (see glp_get_unbnd_ray()). The unset value is equivalent to
253        false. Rays are only available when solving linear programs, they are not
254        available for MIPs. On top of that they are only available when using a
255        simplex algorithm with the presolve disabled. A primal ray can only be
256        built if the chosen LP algorithm is LPAlgorithm.PRIMAL_SIMPLEX. Same for a
257        dual ray and LPAlgorithm.DUAL_SIMPLEX. The computation involves the basis
258        factorization to be available which may lead to extra computations/errors.
259    """
260
261    compute_unbound_rays_if_possible: Optional[bool] = None
262
263    def to_proto(self) -> glpk_pb2.GlpkParametersProto:
264        return glpk_pb2.GlpkParametersProto(
265            compute_unbound_rays_if_possible=self.compute_unbound_rays_if_possible
266        )
267
268
269@dataclasses.dataclass
270class SolveParameters:
271    """Parameters to control a single solve.
272
273  If a value is set in both common and solver specific field (e.g. gscip), the
274  solver specific setting is used.
275
276  Solver specific parameters for solvers other than the one in use are ignored.
277
278  Parameters that depends on the model (e.g. branching priority is set for each
279  variable) are passed in ModelSolveParameters.
280
281  See solve() and IncrementalSolver.solve() in solve.py for more details.
282
283  Attributes:
284    time_limit: The maximum time a solver should spend on the problem, or if
285      None, then the time limit is infinite. This value is not a hard limit,
286      solve time may slightly exceed this value. This parameter is always passed
287      to the underlying solver, the solver default is not used.
288    iteration_limit: Limit on the iterations of the underlying algorithm (e.g.
289      simplex pivots). The specific behavior is dependent on the solver and
290      algorithm used, but often can give a deterministic solve limit (further
291      configuration may be needed, e.g. one thread). Typically supported by LP,
292      QP, and MIP solvers, but for MIP solvers see also node_limit.
293    node_limit: Limit on the number of subproblems solved in enumerative search
294      (e.g. branch and bound). For many solvers this can be used to
295      deterministically limit computation (further configuration may be needed,
296      e.g. one thread). Typically for MIP solvers, see also iteration_limit.
297    cutoff_limit: The solver stops early if it can prove there are no primal
298      solutions at least as good as cutoff. On an early stop, the solver returns
299      TerminationReason.NO_SOLUTION_FOUND and with Limit.CUTOFF and is not
300      required to give any extra solution information. Has no effect on the
301      return value if there is no early stop. It is recommended that you use a
302      tolerance if you want solutions with objective exactly equal to cutoff to
303      be returned. See the user guide for more details and a comparison with
304      best_bound_limit.
305    objective_limit: The solver stops early as soon as it finds a solution at
306      least this good, with TerminationReason.FEASIBLE and Limit.OBJECTIVE.
307    best_bound_limit: The solver stops early as soon as it proves the best bound
308      is at least this good, with TerminationReason of FEASIBLE or
309      NO_SOLUTION_FOUND and Limit.OBJECTIVE. See the user guide for more details
310      and a comparison with cutoff_limit.
311    solution_limit: The solver stops early after finding this many feasible
312      solutions, with TerminationReason.FEASIBLE and Limit.SOLUTION. Must be
313      greater than zero if set. It is often used get the solver to stop on the
314      first feasible solution found. Note that there is no guarantee on the
315      objective value for any of the returned solutions. Solvers will typically
316      not return more solutions than the solution limit, but this is not
317      enforced by MathOpt, see also b/214041169. Currently supported for Gurobi
318      and SCIP, and for CP-SAT only with value 1.
319    enable_output: If the solver should print out its log messages.
320    threads: An integer >= 1, how many threads to use when solving.
321    random_seed: Seed for the pseudo-random number generator in the underlying
322      solver. Note that valid values depend on the actual solver:
323        * Gurobi: [0:GRB_MAXINT] (which as of Gurobi 9.0 is 2x10^9).
324        * GSCIP: [0:2147483647] (which is MAX_INT or kint32max or 2^31-1).
325        * GLOP: [0:2147483647] (same as above).
326      In all cases, the solver will receive a value equal to:
327      MAX(0, MIN(MAX_VALID_VALUE_FOR_SOLVER, random_seed)).
328    absolute_gap_tolerance: An absolute optimality tolerance (primarily) for MIP
329      solvers. The absolute GAP is the absolute value of the difference between:
330        * the objective value of the best feasible solution found,
331        * the dual bound produced by the search.
332      The solver can stop once the absolute GAP is at most
333      absolute_gap_tolerance (when set), and return TerminationReason.OPTIMAL.
334      Must be >= 0 if set. See also relative_gap_tolerance.
335    relative_gap_tolerance: A relative optimality tolerance (primarily) for MIP
336      solvers. The relative GAP is a normalized version of the absolute GAP
337      (defined on absolute_gap_tolerance), where the normalization is
338      solver-dependent, e.g. the absolute GAP divided by the objective value of
339      the best feasible solution found. The solver can stop once the relative
340      GAP is at most relative_gap_tolerance (when set), and return
341      TerminationReason.OPTIMAL. Must be >= 0 if set. See also
342      absolute_gap_tolerance.
343    solution_pool_size: Maintain up to `solution_pool_size` solutions while
344      searching. The solution pool generally has two functions:
345        * For solvers that can return more than one solution, this limits how
346          many solutions will be returned.
347        * Some solvers may run heuristics using solutions from the solution
348          pool, so changing this value may affect the algorithm's path.
349      To force the solver to fill the solution pool, e.g. with the n best
350      solutions, requires further, solver specific configuration.
351    lp_algorithm: The algorithm for solving a linear program. If UNSPECIFIED,
352      use the solver default algorithm. For problems that are not linear
353      programs but where linear programming is a subroutine, solvers may use
354      this value. E.g. MIP solvers will typically use this for the root LP solve
355      only (and use dual simplex otherwise).
356    presolve: Effort on simplifying the problem before starting the main
357      algorithm (e.g. simplex).
358    cuts: Effort on getting a stronger LP relaxation (MIP only). Note that in
359      some solvers, disabling cuts may prevent callbacks from having a chance to
360      add cuts at MIP_NODE.
361    heuristics: Effort in finding feasible solutions beyond those encountered in
362      the complete search procedure.
363    scaling: Effort in rescaling the problem to improve numerical stability.
364    gscip: GSCIP specific solve parameters.
365    gurobi: Gurobi specific solve parameters.
366    glop: Glop specific solve parameters.
367    cp_sat: CP-SAT specific solve parameters.
368    pdlp: PDLP specific solve parameters.
369    osqp: OSQP specific solve parameters. Users should prefer the generic
370      MathOpt parameters over OSQP-level parameters, when available: - Prefer
371      SolveParameters.enable_output to OsqpSettingsProto.verbose. - Prefer
372      SolveParameters.time_limit to OsqpSettingsProto.time_limit. - Prefer
373      SolveParameters.iteration_limit to OsqpSettingsProto.iteration_limit. - If
374      a less granular configuration is acceptable, prefer
375      SolveParameters.scaling to OsqpSettingsProto.
376    glpk: GLPK specific solve parameters.
377    highs: HiGHS specific solve parameters.
378  """  # fmt: skip
379
380    time_limit: Optional[datetime.timedelta] = None
381    iteration_limit: Optional[int] = None
382    node_limit: Optional[int] = None
383    cutoff_limit: Optional[float] = None
384    objective_limit: Optional[float] = None
385    best_bound_limit: Optional[float] = None
386    solution_limit: Optional[int] = None
387    enable_output: bool = False
388    threads: Optional[int] = None
389    random_seed: Optional[int] = None
390    absolute_gap_tolerance: Optional[float] = None
391    relative_gap_tolerance: Optional[float] = None
392    solution_pool_size: Optional[int] = None
393    lp_algorithm: Optional[LPAlgorithm] = None
394    presolve: Optional[Emphasis] = None
395    cuts: Optional[Emphasis] = None
396    heuristics: Optional[Emphasis] = None
397    scaling: Optional[Emphasis] = None
398    gscip: gscip_pb2.GScipParameters = dataclasses.field(
399        default_factory=gscip_pb2.GScipParameters
400    )
401    gurobi: GurobiParameters = dataclasses.field(default_factory=GurobiParameters)
402    glop: glop_parameters_pb2.GlopParameters = dataclasses.field(
403        default_factory=glop_parameters_pb2.GlopParameters
404    )
405    cp_sat: sat_parameters_pb2.SatParameters = dataclasses.field(
406        default_factory=sat_parameters_pb2.SatParameters
407    )
408    pdlp: pdlp_solvers_pb2.PrimalDualHybridGradientParams = dataclasses.field(
409        default_factory=pdlp_solvers_pb2.PrimalDualHybridGradientParams
410    )
411    osqp: osqp_pb2.OsqpSettingsProto = dataclasses.field(
412        default_factory=osqp_pb2.OsqpSettingsProto
413    )
414    glpk: GlpkParameters = dataclasses.field(default_factory=GlpkParameters)
415    highs: highs_pb2.HighsOptionsProto = dataclasses.field(
416        default_factory=highs_pb2.HighsOptionsProto
417    )
418
419    def to_proto(self) -> math_opt_parameters_pb2.SolveParametersProto:
420        """Returns a protocol buffer equivalent to this."""
421        result = math_opt_parameters_pb2.SolveParametersProto(
422            enable_output=self.enable_output,
423            lp_algorithm=lp_algorithm_to_proto(self.lp_algorithm),
424            presolve=emphasis_to_proto(self.presolve),
425            cuts=emphasis_to_proto(self.cuts),
426            heuristics=emphasis_to_proto(self.heuristics),
427            scaling=emphasis_to_proto(self.scaling),
428            gscip=self.gscip,
429            gurobi=self.gurobi.to_proto(),
430            glop=self.glop,
431            cp_sat=self.cp_sat,
432            pdlp=self.pdlp,
433            osqp=self.osqp,
434            glpk=self.glpk.to_proto(),
435            highs=self.highs,
436        )
437        if self.time_limit is not None:
438            result.time_limit.FromTimedelta(self.time_limit)
439        if self.iteration_limit is not None:
440            result.iteration_limit = self.iteration_limit
441        if self.node_limit is not None:
442            result.node_limit = self.node_limit
443        if self.cutoff_limit is not None:
444            result.cutoff_limit = self.cutoff_limit
445        if self.objective_limit is not None:
446            result.objective_limit = self.objective_limit
447        if self.best_bound_limit is not None:
448            result.best_bound_limit = self.best_bound_limit
449        if self.solution_limit is not None:
450            result.solution_limit = self.solution_limit
451        if self.threads is not None:
452            result.threads = self.threads
453        if self.random_seed is not None:
454            result.random_seed = self.random_seed
455        if self.absolute_gap_tolerance is not None:
456            result.absolute_gap_tolerance = self.absolute_gap_tolerance
457        if self.relative_gap_tolerance is not None:
458            result.relative_gap_tolerance = self.relative_gap_tolerance
459        if self.solution_pool_size is not None:
460            result.solution_pool_size = self.solution_pool_size
461        return result
@enum.unique
class SolverType(enum.Enum):
34@enum.unique
35class SolverType(enum.Enum):
36    """The underlying solver to use.
37
38    This must stay synchronized with math_opt_parameters_pb2.SolverTypeProto.
39
40    Attributes:
41      GSCIP: Solving Constraint Integer Programs (SCIP) solver (third party).
42        Supports LP, MIP, and nonconvex integer quadratic problems. No dual data
43        for LPs is returned though. Prefer GLOP for LPs.
44      GUROBI: Gurobi solver (third party). Supports LP, MIP, and nonconvex integer
45        quadratic problems. Generally the fastest option, but has special
46        licensing, see go/gurobi-google for details.
47      GLOP: Google's Glop linear solver. Supports LP with primal and dual simplex
48        methods.
49      CP_SAT: Google's CP-SAT solver. Supports problems where all variables are
50        integer and bounded (or implied to be after presolve). Experimental
51        support to rescale and discretize problems with continuous variables.
52      MOE:begin_intracomment_strip
53      PDLP: Google's PDLP solver. Supports LP and convex diagonal quadratic
54        objectives. Uses first order methods rather than simplex. Can solve very
55        large problems.
56      MOE:end_intracomment_strip
57      GLPK: GNU Linear Programming Kit (GLPK) (third party). Supports MIP and LP.
58        Thread-safety: GLPK use thread-local storage for memory allocations. As a
59        consequence when using IncrementalSolver, the user must make sure that
60        instances are closed on the same thread as they are created or GLPK will
61        crash. To do so, use `with` or call IncrementalSolver#close(). It seems OK
62        to call IncrementalSolver#Solve() from another thread than the one used to
63        create the Solver but it is not documented by GLPK and should be avoided.
64        Of course these limitations do not apply to the solve() function that
65        recreates a new GLPK problem in the calling thread and destroys before
66        returning.  When solving a LP with the presolver, a solution (and the
67        unbound rays) are only returned if an optimal solution has been found.
68        Else nothing is returned. See glpk-5.0/doc/glpk.pdf page #40 available
69        from glpk-5.0.tar.gz for details.
70      OSQP: The Operator Splitting Quadratic Program (OSQP) solver (third party).
71        Supports continuous problems with linear constraints and linear or convex
72        quadratic objectives. Uses a first-order method.
73      ECOS: The Embedded Conic Solver (ECOS) (third party). Supports LP and SOCP
74        problems. Uses interior point methods (barrier).
75      SCS: The Splitting Conic Solver (SCS) (third party). Supports LP and SOCP
76        problems. Uses a first-order method.
77      HIGHS: The HiGHS Solver (third party). Supports LP and MIP problems (convex
78        QPs are unimplemented).
79      SANTORINI: The Santorini Solver (first party). Supports MIP. Experimental,
80        do not use in production.
81    """
82
83    GSCIP = math_opt_parameters_pb2.SOLVER_TYPE_GSCIP
84    GUROBI = math_opt_parameters_pb2.SOLVER_TYPE_GUROBI
85    GLOP = math_opt_parameters_pb2.SOLVER_TYPE_GLOP
86    CP_SAT = math_opt_parameters_pb2.SOLVER_TYPE_CP_SAT
87    PDLP = math_opt_parameters_pb2.SOLVER_TYPE_PDLP
88    GLPK = math_opt_parameters_pb2.SOLVER_TYPE_GLPK
89    OSQP = math_opt_parameters_pb2.SOLVER_TYPE_OSQP
90    ECOS = math_opt_parameters_pb2.SOLVER_TYPE_ECOS
91    SCS = math_opt_parameters_pb2.SOLVER_TYPE_SCS
92    HIGHS = math_opt_parameters_pb2.SOLVER_TYPE_HIGHS
93    SANTORINI = math_opt_parameters_pb2.SOLVER_TYPE_SANTORINI

The underlying solver to use.

This must stay synchronized with math_opt_parameters_pb2.SolverTypeProto.

Attributes:
  • 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.
  • GUROBI: Gurobi solver (third party). Supports LP, MIP, and nonconvex integer quadratic problems. Generally the fastest option, but has special licensing, see go/gurobi-google for details.
  • GLOP: Google's Glop linear solver. Supports LP with primal and dual simplex methods.
  • 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.
  • MOE: begin_intracomment_strip
  • PDLP: Google's PDLP solver. Supports LP and convex diagonal quadratic objectives. Uses first order methods rather than simplex. Can solve very large problems.
  • MOE: end_intracomment_strip
  • 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 when using IncrementalSolver, the user must make sure that instances are closed on the same thread as they are created or GLPK will crash. To do so, use with or call IncrementalSolver#close(). It seems OK to call IncrementalSolver#Solve() from another thread than the one used to create the Solver but it is not documented by GLPK and should be avoided. Of course these limitations do not apply to the solve() function that recreates a new GLPK problem in the calling thread and destroys before returning. 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.
  • 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.
  • ECOS: The Embedded Conic Solver (ECOS) (third party). Supports LP and SOCP problems. Uses interior point methods (barrier).
  • SCS: The Splitting Conic Solver (SCS) (third party). Supports LP and SOCP problems. Uses a first-order method.
  • HIGHS: The HiGHS Solver (third party). Supports LP and MIP problems (convex QPs are unimplemented).
  • SANTORINI: The Santorini Solver (first party). Supports MIP. Experimental, do not use in production.
GSCIP = <SolverType.GSCIP: 1>
GUROBI = <SolverType.GUROBI: 2>
GLOP = <SolverType.GLOP: 3>
CP_SAT = <SolverType.CP_SAT: 4>
PDLP = <SolverType.PDLP: 5>
GLPK = <SolverType.GLPK: 6>
OSQP = <SolverType.OSQP: 7>
ECOS = <SolverType.ECOS: 8>
SCS = <SolverType.SCS: 9>
HIGHS = <SolverType.HIGHS: 10>
SANTORINI = <SolverType.SANTORINI: 11>
def solver_type_from_proto( proto_value: <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object>) -> SolverType | None:
 96def solver_type_from_proto(
 97    proto_value: math_opt_parameters_pb2.SolverTypeProto,
 98) -> Optional[SolverType]:
 99    if proto_value == math_opt_parameters_pb2.SOLVER_TYPE_UNSPECIFIED:
100        return None
101    return SolverType(proto_value)
def solver_type_to_proto( solver_type: SolverType | None) -> <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object at 0x7f351753e9c0>:
104def solver_type_to_proto(
105    solver_type: Optional[SolverType],
106) -> math_opt_parameters_pb2.SolverTypeProto:
107    if solver_type is None:
108        return math_opt_parameters_pb2.SOLVER_TYPE_UNSPECIFIED
109    return solver_type.value
@enum.unique
class LPAlgorithm(enum.Enum):
112@enum.unique
113class LPAlgorithm(enum.Enum):
114    """Selects an algorithm for solving linear programs.
115
116    Attributes:
117      * UNPSECIFIED: No algorithm is selected.
118      * PRIMAL_SIMPLEX: The (primal) simplex method. Typically can provide primal
119        and dual solutions, primal/dual rays on primal/dual unbounded problems,
120        and a basis.
121      * DUAL_SIMPLEX: The dual simplex method. Typically can provide primal and
122        dual solutions, primal/dual rays on primal/dual unbounded problems, and a
123        basis.
124      * BARRIER: The barrier method, also commonly called an interior point method
125        (IPM). Can typically give both primal and dual solutions. Some
126        implementations can also produce rays on unbounded/infeasible problems. A
127        basis is not given unless the underlying solver does "crossover" and
128        finishes with simplex.
129      * FIRST_ORDER: An algorithm based around a first-order method. These will
130        typically produce both primal and dual solutions, and potentially also
131        certificates of primal and/or dual infeasibility. First-order methods
132        typically will provide solutions with lower accuracy, so users should take
133        care to set solution quality parameters (e.g., tolerances) and to validate
134        solutions.
135
136    This must stay synchronized with math_opt_parameters_pb2.LPAlgorithmProto.
137    """
138
139    PRIMAL_SIMPLEX = math_opt_parameters_pb2.LP_ALGORITHM_PRIMAL_SIMPLEX
140    DUAL_SIMPLEX = math_opt_parameters_pb2.LP_ALGORITHM_DUAL_SIMPLEX
141    BARRIER = math_opt_parameters_pb2.LP_ALGORITHM_BARRIER
142    FIRST_ORDER = math_opt_parameters_pb2.LP_ALGORITHM_FIRST_ORDER

Selects an algorithm for solving linear programs.

Attributes:
  • * UNPSECIFIED: No algorithm is selected.
  • * PRIMAL_SIMPLEX: The (primal) simplex method. Typically can provide primal and dual solutions, primal/dual rays on primal/dual unbounded problems, and a basis.
  • * DUAL_SIMPLEX: The dual simplex method. Typically can provide primal and dual solutions, primal/dual rays on primal/dual unbounded problems, and a basis.
  • * 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.
  • * 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.

This must stay synchronized with math_opt_parameters_pb2.LPAlgorithmProto.

PRIMAL_SIMPLEX = <LPAlgorithm.PRIMAL_SIMPLEX: 1>
DUAL_SIMPLEX = <LPAlgorithm.DUAL_SIMPLEX: 2>
BARRIER = <LPAlgorithm.BARRIER: 3>
FIRST_ORDER = <LPAlgorithm.FIRST_ORDER: 4>
def lp_algorithm_from_proto( proto_value: <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object>) -> LPAlgorithm | None:
145def lp_algorithm_from_proto(
146    proto_value: math_opt_parameters_pb2.LPAlgorithmProto,
147) -> Optional[LPAlgorithm]:
148    if proto_value == math_opt_parameters_pb2.LP_ALGORITHM_UNSPECIFIED:
149        return None
150    return LPAlgorithm(proto_value)
def lp_algorithm_to_proto( lp_algorithm: LPAlgorithm | None) -> <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object at 0x7f351755ca10>:
153def lp_algorithm_to_proto(
154    lp_algorithm: Optional[LPAlgorithm],
155) -> math_opt_parameters_pb2.LPAlgorithmProto:
156    if lp_algorithm is None:
157        return math_opt_parameters_pb2.LP_ALGORITHM_UNSPECIFIED
158    return lp_algorithm.value
@enum.unique
class Emphasis(enum.Enum):
161@enum.unique
162class Emphasis(enum.Enum):
163    """Effort level applied to an optional task while solving (see SolveParameters for use).
164
165    - OFF: disable this task.
166    - LOW: apply reduced effort.
167    - MEDIUM: typically the default setting (unless the default is off).
168    - HIGH: apply extra effort beyond MEDIUM.
169    - VERY_HIGH: apply the maximum effort.
170
171    Typically used as Optional[Emphasis]. It used to configure a solver feature as
172    follows:
173      * If a solver doesn't support the feature, only None will always be valid,
174        any other setting will give an invalid argument error (some solvers may
175        also accept OFF).
176      * If the solver supports the feature:
177        - When set to None, the underlying default is used.
178        - When the feature cannot be turned off, OFF will produce an error.
179        - If the feature is enabled by default, the solver default is typically
180          mapped to MEDIUM.
181        - If the feature is supported, LOW, MEDIUM, HIGH, and VERY HIGH will never
182          give an error, and will map onto their best match.
183
184    This must stay synchronized with math_opt_parameters_pb2.EmphasisProto.
185    """
186
187    OFF = math_opt_parameters_pb2.EMPHASIS_OFF
188    LOW = math_opt_parameters_pb2.EMPHASIS_LOW
189    MEDIUM = math_opt_parameters_pb2.EMPHASIS_MEDIUM
190    HIGH = math_opt_parameters_pb2.EMPHASIS_HIGH
191    VERY_HIGH = math_opt_parameters_pb2.EMPHASIS_VERY_HIGH

Effort level applied to an optional task while solving (see SolveParameters for use).

  • OFF: disable this task.
  • LOW: apply reduced effort.
  • MEDIUM: typically the default setting (unless the default is off).
  • HIGH: apply extra effort beyond MEDIUM.
  • VERY_HIGH: apply the maximum effort.

Typically used as Optional[Emphasis]. It used to configure a solver feature as follows:

  • If a solver doesn't support the feature, only None will always be valid, any other setting will give an invalid argument error (some solvers may also accept OFF).
  • If the solver supports the feature:
    • When set to None, the underlying default is used.
    • When the feature cannot be turned off, OFF will produce 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.

This must stay synchronized with math_opt_parameters_pb2.EmphasisProto.

OFF = <Emphasis.OFF: 1>
LOW = <Emphasis.LOW: 2>
MEDIUM = <Emphasis.MEDIUM: 3>
HIGH = <Emphasis.HIGH: 4>
VERY_HIGH = <Emphasis.VERY_HIGH: 5>
def emphasis_from_proto( proto_value: <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object>) -> Emphasis | None:
194def emphasis_from_proto(
195    proto_value: math_opt_parameters_pb2.EmphasisProto,
196) -> Optional[Emphasis]:
197    if proto_value == math_opt_parameters_pb2.EMPHASIS_UNSPECIFIED:
198        return None
199    return Emphasis(proto_value)
def emphasis_to_proto( emphasis: Emphasis | None) -> <google.protobuf.internal.enum_type_wrapper.EnumTypeWrapper object at 0x7f351755cd10>:
202def emphasis_to_proto(
203    emphasis: Optional[Emphasis],
204) -> math_opt_parameters_pb2.EmphasisProto:
205    if emphasis is None:
206        return math_opt_parameters_pb2.EMPHASIS_UNSPECIFIED
207    return emphasis.value
@dataclasses.dataclass
class GurobiParameters:
210@dataclasses.dataclass
211class GurobiParameters:
212    """Gurobi specific parameters for solving.
213
214    See https://www.gurobi.com/documentation/9.1/refman/parameters.html for a list
215    of possible parameters.
216
217    Example use:
218      gurobi=GurobiParameters();
219      gurobi.param_values["BarIterLimit"] = "10";
220
221    With Gurobi, the order that parameters are applied can have an impact in rare
222    situations. Parameters are applied in the following order:
223     * LogToConsole is set from SolveParameters.enable_output.
224     * Any common parameters not overwritten by GurobiParameters.
225     * param_values in iteration order (insertion order).
226    We set LogToConsole first because setting other parameters can generate
227    output.
228    """
229
230    param_values: Dict[str, str] = dataclasses.field(default_factory=dict)
231
232    def to_proto(self) -> gurobi_pb2.GurobiParametersProto:
233        return gurobi_pb2.GurobiParametersProto(
234            parameters=[
235                gurobi_pb2.GurobiParametersProto.Parameter(name=key, value=val)
236                for key, val in self.param_values.items()
237            ]
238        )

Gurobi specific parameters for solving.

See https://www.gurobi.com/documentation/9.1/refman/parameters.html for a list of possible parameters.

Example use:

gurobi=GurobiParameters(); gurobi.param_values["BarIterLimit"] = "10";

With Gurobi, the order that parameters are applied can have an impact in rare situations. Parameters are applied in the following order:

  • LogToConsole is set from SolveParameters.enable_output.
  • Any common parameters not overwritten by GurobiParameters.
  • param_values in iteration order (insertion order). We set LogToConsole first because setting other parameters can generate output.
GurobiParameters(param_values: Dict[str, str] = <factory>)
param_values: Dict[str, str]
232    def to_proto(self) -> gurobi_pb2.GurobiParametersProto:
233        return gurobi_pb2.GurobiParametersProto(
234            parameters=[
235                gurobi_pb2.GurobiParametersProto.Parameter(name=key, value=val)
236                for key, val in self.param_values.items()
237            ]
238        )
@dataclasses.dataclass
class GlpkParameters:
241@dataclasses.dataclass
242class GlpkParameters:
243    """GLPK specific parameters for solving.
244
245    Fields are optional to enable to capture user intention; if they set
246    explicitly a value to then no generic solve parameters will overwrite this
247    parameter. User specified solver specific parameters have priority on generic
248    parameters.
249
250    Attributes:
251      compute_unbound_rays_if_possible: Compute the primal or dual unbound ray
252        when the variable (structural or auxiliary) causing the unboundness is
253        identified (see glp_get_unbnd_ray()). The unset value is equivalent to
254        false. Rays are only available when solving linear programs, they are not
255        available for MIPs. On top of that they are only available when using a
256        simplex algorithm with the presolve disabled. A primal ray can only be
257        built if the chosen LP algorithm is LPAlgorithm.PRIMAL_SIMPLEX. Same for a
258        dual ray and LPAlgorithm.DUAL_SIMPLEX. The computation involves the basis
259        factorization to be available which may lead to extra computations/errors.
260    """
261
262    compute_unbound_rays_if_possible: Optional[bool] = None
263
264    def to_proto(self) -> glpk_pb2.GlpkParametersProto:
265        return glpk_pb2.GlpkParametersProto(
266            compute_unbound_rays_if_possible=self.compute_unbound_rays_if_possible
267        )

GLPK specific parameters for solving.

Fields are optional to enable to capture user intention; if they set explicitly a value to then no generic solve parameters will overwrite this parameter. User specified solver specific parameters have priority on generic parameters.

Attributes:
  • compute_unbound_rays_if_possible: Compute the primal or dual unbound ray when the variable (structural or auxiliary) causing the unboundness is identified (see glp_get_unbnd_ray()). The unset value is equivalent to false. Rays are only available when solving linear programs, they are not available for MIPs. On top of that they are only available when using a simplex algorithm with the presolve disabled. A primal ray can only be built if the chosen LP algorithm is LPAlgorithm.PRIMAL_SIMPLEX. Same for a dual ray and LPAlgorithm.DUAL_SIMPLEX. The computation involves the basis factorization to be available which may lead to extra computations/errors.
GlpkParameters(compute_unbound_rays_if_possible: bool | None = None)
compute_unbound_rays_if_possible: bool | None = None
def to_proto(self) -> ortools.math_opt.solvers.glpk_pb2.GlpkParametersProto:
264    def to_proto(self) -> glpk_pb2.GlpkParametersProto:
265        return glpk_pb2.GlpkParametersProto(
266            compute_unbound_rays_if_possible=self.compute_unbound_rays_if_possible
267        )
@dataclasses.dataclass
class SolveParameters:
270@dataclasses.dataclass
271class SolveParameters:
272    """Parameters to control a single solve.
273
274  If a value is set in both common and solver specific field (e.g. gscip), the
275  solver specific setting is used.
276
277  Solver specific parameters for solvers other than the one in use are ignored.
278
279  Parameters that depends on the model (e.g. branching priority is set for each
280  variable) are passed in ModelSolveParameters.
281
282  See solve() and IncrementalSolver.solve() in solve.py for more details.
283
284  Attributes:
285    time_limit: The maximum time a solver should spend on the problem, or if
286      None, then the time limit is infinite. This value is not a hard limit,
287      solve time may slightly exceed this value. This parameter is always passed
288      to the underlying solver, the solver default is not used.
289    iteration_limit: Limit on the iterations of the underlying algorithm (e.g.
290      simplex pivots). The specific behavior is dependent on the solver and
291      algorithm used, but often can give a deterministic solve limit (further
292      configuration may be needed, e.g. one thread). Typically supported by LP,
293      QP, and MIP solvers, but for MIP solvers see also node_limit.
294    node_limit: Limit on the number of subproblems solved in enumerative search
295      (e.g. branch and bound). For many solvers this can be used to
296      deterministically limit computation (further configuration may be needed,
297      e.g. one thread). Typically for MIP solvers, see also iteration_limit.
298    cutoff_limit: The solver stops early if it can prove there are no primal
299      solutions at least as good as cutoff. On an early stop, the solver returns
300      TerminationReason.NO_SOLUTION_FOUND and with Limit.CUTOFF and is not
301      required to give any extra solution information. Has no effect on the
302      return value if there is no early stop. It is recommended that you use a
303      tolerance if you want solutions with objective exactly equal to cutoff to
304      be returned. See the user guide for more details and a comparison with
305      best_bound_limit.
306    objective_limit: The solver stops early as soon as it finds a solution at
307      least this good, with TerminationReason.FEASIBLE and Limit.OBJECTIVE.
308    best_bound_limit: The solver stops early as soon as it proves the best bound
309      is at least this good, with TerminationReason of FEASIBLE or
310      NO_SOLUTION_FOUND and Limit.OBJECTIVE. See the user guide for more details
311      and a comparison with cutoff_limit.
312    solution_limit: The solver stops early after finding this many feasible
313      solutions, with TerminationReason.FEASIBLE and Limit.SOLUTION. Must be
314      greater than zero if set. It is often used get the solver to stop on the
315      first feasible solution found. Note that there is no guarantee on the
316      objective value for any of the returned solutions. Solvers will typically
317      not return more solutions than the solution limit, but this is not
318      enforced by MathOpt, see also b/214041169. Currently supported for Gurobi
319      and SCIP, and for CP-SAT only with value 1.
320    enable_output: If the solver should print out its log messages.
321    threads: An integer >= 1, how many threads to use when solving.
322    random_seed: Seed for the pseudo-random number generator in the underlying
323      solver. Note that valid values depend on the actual solver:
324        * Gurobi: [0:GRB_MAXINT] (which as of Gurobi 9.0 is 2x10^9).
325        * GSCIP: [0:2147483647] (which is MAX_INT or kint32max or 2^31-1).
326        * GLOP: [0:2147483647] (same as above).
327      In all cases, the solver will receive a value equal to:
328      MAX(0, MIN(MAX_VALID_VALUE_FOR_SOLVER, random_seed)).
329    absolute_gap_tolerance: An absolute optimality tolerance (primarily) for MIP
330      solvers. The absolute GAP is the absolute value of the difference between:
331        * the objective value of the best feasible solution found,
332        * the dual bound produced by the search.
333      The solver can stop once the absolute GAP is at most
334      absolute_gap_tolerance (when set), and return TerminationReason.OPTIMAL.
335      Must be >= 0 if set. See also relative_gap_tolerance.
336    relative_gap_tolerance: A relative optimality tolerance (primarily) for MIP
337      solvers. The relative GAP is a normalized version of the absolute GAP
338      (defined on absolute_gap_tolerance), where the normalization is
339      solver-dependent, e.g. the absolute GAP divided by the objective value of
340      the best feasible solution found. The solver can stop once the relative
341      GAP is at most relative_gap_tolerance (when set), and return
342      TerminationReason.OPTIMAL. Must be >= 0 if set. See also
343      absolute_gap_tolerance.
344    solution_pool_size: Maintain up to `solution_pool_size` solutions while
345      searching. The solution pool generally has two functions:
346        * For solvers that can return more than one solution, this limits how
347          many solutions will be returned.
348        * Some solvers may run heuristics using solutions from the solution
349          pool, so changing this value may affect the algorithm's path.
350      To force the solver to fill the solution pool, e.g. with the n best
351      solutions, requires further, solver specific configuration.
352    lp_algorithm: The algorithm for solving a linear program. If UNSPECIFIED,
353      use the solver default algorithm. For problems that are not linear
354      programs but where linear programming is a subroutine, solvers may use
355      this value. E.g. MIP solvers will typically use this for the root LP solve
356      only (and use dual simplex otherwise).
357    presolve: Effort on simplifying the problem before starting the main
358      algorithm (e.g. simplex).
359    cuts: Effort on getting a stronger LP relaxation (MIP only). Note that in
360      some solvers, disabling cuts may prevent callbacks from having a chance to
361      add cuts at MIP_NODE.
362    heuristics: Effort in finding feasible solutions beyond those encountered in
363      the complete search procedure.
364    scaling: Effort in rescaling the problem to improve numerical stability.
365    gscip: GSCIP specific solve parameters.
366    gurobi: Gurobi specific solve parameters.
367    glop: Glop specific solve parameters.
368    cp_sat: CP-SAT specific solve parameters.
369    pdlp: PDLP specific solve parameters.
370    osqp: OSQP specific solve parameters. Users should prefer the generic
371      MathOpt parameters over OSQP-level parameters, when available: - Prefer
372      SolveParameters.enable_output to OsqpSettingsProto.verbose. - Prefer
373      SolveParameters.time_limit to OsqpSettingsProto.time_limit. - Prefer
374      SolveParameters.iteration_limit to OsqpSettingsProto.iteration_limit. - If
375      a less granular configuration is acceptable, prefer
376      SolveParameters.scaling to OsqpSettingsProto.
377    glpk: GLPK specific solve parameters.
378    highs: HiGHS specific solve parameters.
379  """  # fmt: skip
380
381    time_limit: Optional[datetime.timedelta] = None
382    iteration_limit: Optional[int] = None
383    node_limit: Optional[int] = None
384    cutoff_limit: Optional[float] = None
385    objective_limit: Optional[float] = None
386    best_bound_limit: Optional[float] = None
387    solution_limit: Optional[int] = None
388    enable_output: bool = False
389    threads: Optional[int] = None
390    random_seed: Optional[int] = None
391    absolute_gap_tolerance: Optional[float] = None
392    relative_gap_tolerance: Optional[float] = None
393    solution_pool_size: Optional[int] = None
394    lp_algorithm: Optional[LPAlgorithm] = None
395    presolve: Optional[Emphasis] = None
396    cuts: Optional[Emphasis] = None
397    heuristics: Optional[Emphasis] = None
398    scaling: Optional[Emphasis] = None
399    gscip: gscip_pb2.GScipParameters = dataclasses.field(
400        default_factory=gscip_pb2.GScipParameters
401    )
402    gurobi: GurobiParameters = dataclasses.field(default_factory=GurobiParameters)
403    glop: glop_parameters_pb2.GlopParameters = dataclasses.field(
404        default_factory=glop_parameters_pb2.GlopParameters
405    )
406    cp_sat: sat_parameters_pb2.SatParameters = dataclasses.field(
407        default_factory=sat_parameters_pb2.SatParameters
408    )
409    pdlp: pdlp_solvers_pb2.PrimalDualHybridGradientParams = dataclasses.field(
410        default_factory=pdlp_solvers_pb2.PrimalDualHybridGradientParams
411    )
412    osqp: osqp_pb2.OsqpSettingsProto = dataclasses.field(
413        default_factory=osqp_pb2.OsqpSettingsProto
414    )
415    glpk: GlpkParameters = dataclasses.field(default_factory=GlpkParameters)
416    highs: highs_pb2.HighsOptionsProto = dataclasses.field(
417        default_factory=highs_pb2.HighsOptionsProto
418    )
419
420    def to_proto(self) -> math_opt_parameters_pb2.SolveParametersProto:
421        """Returns a protocol buffer equivalent to this."""
422        result = math_opt_parameters_pb2.SolveParametersProto(
423            enable_output=self.enable_output,
424            lp_algorithm=lp_algorithm_to_proto(self.lp_algorithm),
425            presolve=emphasis_to_proto(self.presolve),
426            cuts=emphasis_to_proto(self.cuts),
427            heuristics=emphasis_to_proto(self.heuristics),
428            scaling=emphasis_to_proto(self.scaling),
429            gscip=self.gscip,
430            gurobi=self.gurobi.to_proto(),
431            glop=self.glop,
432            cp_sat=self.cp_sat,
433            pdlp=self.pdlp,
434            osqp=self.osqp,
435            glpk=self.glpk.to_proto(),
436            highs=self.highs,
437        )
438        if self.time_limit is not None:
439            result.time_limit.FromTimedelta(self.time_limit)
440        if self.iteration_limit is not None:
441            result.iteration_limit = self.iteration_limit
442        if self.node_limit is not None:
443            result.node_limit = self.node_limit
444        if self.cutoff_limit is not None:
445            result.cutoff_limit = self.cutoff_limit
446        if self.objective_limit is not None:
447            result.objective_limit = self.objective_limit
448        if self.best_bound_limit is not None:
449            result.best_bound_limit = self.best_bound_limit
450        if self.solution_limit is not None:
451            result.solution_limit = self.solution_limit
452        if self.threads is not None:
453            result.threads = self.threads
454        if self.random_seed is not None:
455            result.random_seed = self.random_seed
456        if self.absolute_gap_tolerance is not None:
457            result.absolute_gap_tolerance = self.absolute_gap_tolerance
458        if self.relative_gap_tolerance is not None:
459            result.relative_gap_tolerance = self.relative_gap_tolerance
460        if self.solution_pool_size is not None:
461            result.solution_pool_size = self.solution_pool_size
462        return result

Parameters to control a single solve.

If a value is set in both common and solver specific field (e.g. gscip), the solver specific setting 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 ModelSolveParameters.

See solve() and IncrementalSolver.solve() in solve.py for more details.

Attributes:
  • time_limit: The maximum time a solver should spend on the problem, or if None, then the time limit is infinite. 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.
  • iteration_limit: 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 node_limit.
  • node_limit: 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 iteration_limit.
  • cutoff_limit: 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 TerminationReason.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 best_bound_limit.
  • objective_limit: The solver stops early as soon as it finds a solution at least this good, with TerminationReason.FEASIBLE and Limit.OBJECTIVE.
  • best_bound_limit: The solver stops early as soon as it proves the best bound is at least this good, with TerminationReason of FEASIBLE or NO_SOLUTION_FOUND and Limit.OBJECTIVE. See the user guide for more details and a comparison with cutoff_limit.
  • solution_limit: The solver stops early after finding this many feasible solutions, with TerminationReason.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.
  • enable_output: If the solver should print out its log messages.
  • threads: An integer >= 1, how many threads to use when solving.
  • random_seed: Seed for the pseudo-random number generator in the underlying solver. 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, random_seed)).
  • absolute_gap_tolerance: 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 absolute_gap_tolerance (when set), and return TerminationReason.OPTIMAL. Must be >= 0 if set. See also relative_gap_tolerance.
  • relative_gap_tolerance: A relative optimality tolerance (primarily) for MIP solvers. The relative GAP is a normalized version of the absolute GAP (defined on absolute_gap_tolerance), 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 relative_gap_tolerance (when set), and return TerminationReason.OPTIMAL. Must be >= 0 if set. See also absolute_gap_tolerance.
  • solution_pool_size: Maintain up to solution_pool_size solutions while searching. The solution pool generally has two functions:
    • For solvers that can return more than one solution, this limits how many solutions will be returned.
    • 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.
  • lp_algorithm: The algorithm for solving a linear program. If 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 (e.g. simplex).
  • cuts: Effort on getting a stronger LP relaxation (MIP only). Note that in some solvers, disabling cuts may prevent callbacks from having a chance to add cuts at MIP_NODE.
  • heuristics: Effort in finding feasible solutions beyond those encountered in the complete search procedure.
  • scaling: Effort in rescaling the problem to improve numerical stability.
  • gscip: GSCIP specific solve parameters.
  • gurobi: Gurobi specific solve parameters.
  • glop: Glop specific solve parameters.
  • cp_sat: CP-SAT specific solve parameters.
  • pdlp: PDLP specific solve parameters.
  • osqp: OSQP specific solve parameters. Users should prefer the generic MathOpt parameters over OSQP-level parameters, when available: - Prefer SolveParameters.enable_output to OsqpSettingsProto.verbose. - Prefer SolveParameters.time_limit to OsqpSettingsProto.time_limit. - Prefer SolveParameters.iteration_limit to OsqpSettingsProto.iteration_limit. - If a less granular configuration is acceptable, prefer SolveParameters.scaling to OsqpSettingsProto.
  • glpk: GLPK specific solve parameters.
  • highs: HiGHS specific solve parameters.
SolveParameters( time_limit: datetime.timedelta | None = None, iteration_limit: int | None = None, node_limit: int | None = None, cutoff_limit: float | None = None, objective_limit: float | None = None, best_bound_limit: float | None = None, solution_limit: int | None = None, enable_output: bool = False, threads: int | None = None, random_seed: int | None = None, absolute_gap_tolerance: float | None = None, relative_gap_tolerance: float | None = None, solution_pool_size: int | None = None, lp_algorithm: LPAlgorithm | None = None, presolve: Emphasis | None = None, cuts: Emphasis | None = None, heuristics: Emphasis | None = None, scaling: Emphasis | None = None, gscip: ortools.math_opt.solvers.gscip.gscip_pb2.GScipParameters = <factory>, gurobi: GurobiParameters = <factory>, glop: ortools.glop.parameters_pb2.GlopParameters = <factory>, cp_sat: ortools.sat.sat_parameters_pb2.SatParameters = <factory>, pdlp: ortools.pdlp.solvers_pb2.PrimalDualHybridGradientParams = <factory>, osqp: ortools.math_opt.solvers.osqp_pb2.OsqpSettingsProto = <factory>, glpk: GlpkParameters = <factory>, highs: ortools.math_opt.solvers.highs_pb2.HighsOptionsProto = <factory>)
time_limit: datetime.timedelta | None = None
iteration_limit: int | None = None
node_limit: int | None = None
cutoff_limit: float | None = None
objective_limit: float | None = None
best_bound_limit: float | None = None
solution_limit: int | None = None
enable_output: bool = False
threads: int | None = None
random_seed: int | None = None
absolute_gap_tolerance: float | None = None
relative_gap_tolerance: float | None = None
solution_pool_size: int | None = None
lp_algorithm: LPAlgorithm | None = None
presolve: Emphasis | None = None
cuts: Emphasis | None = None
heuristics: Emphasis | None = None
scaling: Emphasis | None = None
def to_proto(self) -> ortools.math_opt.parameters_pb2.SolveParametersProto:
420    def to_proto(self) -> math_opt_parameters_pb2.SolveParametersProto:
421        """Returns a protocol buffer equivalent to this."""
422        result = math_opt_parameters_pb2.SolveParametersProto(
423            enable_output=self.enable_output,
424            lp_algorithm=lp_algorithm_to_proto(self.lp_algorithm),
425            presolve=emphasis_to_proto(self.presolve),
426            cuts=emphasis_to_proto(self.cuts),
427            heuristics=emphasis_to_proto(self.heuristics),
428            scaling=emphasis_to_proto(self.scaling),
429            gscip=self.gscip,
430            gurobi=self.gurobi.to_proto(),
431            glop=self.glop,
432            cp_sat=self.cp_sat,
433            pdlp=self.pdlp,
434            osqp=self.osqp,
435            glpk=self.glpk.to_proto(),
436            highs=self.highs,
437        )
438        if self.time_limit is not None:
439            result.time_limit.FromTimedelta(self.time_limit)
440        if self.iteration_limit is not None:
441            result.iteration_limit = self.iteration_limit
442        if self.node_limit is not None:
443            result.node_limit = self.node_limit
444        if self.cutoff_limit is not None:
445            result.cutoff_limit = self.cutoff_limit
446        if self.objective_limit is not None:
447            result.objective_limit = self.objective_limit
448        if self.best_bound_limit is not None:
449            result.best_bound_limit = self.best_bound_limit
450        if self.solution_limit is not None:
451            result.solution_limit = self.solution_limit
452        if self.threads is not None:
453            result.threads = self.threads
454        if self.random_seed is not None:
455            result.random_seed = self.random_seed
456        if self.absolute_gap_tolerance is not None:
457            result.absolute_gap_tolerance = self.absolute_gap_tolerance
458        if self.relative_gap_tolerance is not None:
459            result.relative_gap_tolerance = self.relative_gap_tolerance
460        if self.solution_pool_size is not None:
461            result.solution_pool_size = self.solution_pool_size
462        return result

Returns a protocol buffer equivalent to this.