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
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
withor 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.
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.
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.
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.
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.
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_sizesolutions 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.
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.