-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathparameters.h
More file actions
508 lines (441 loc) · 20.6 KB
/
parameters.h
File metadata and controls
508 lines (441 loc) · 20.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
// Copyright 2010-2026 Google LLC
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// IWYU pragma: private, include "ortools/math_opt/cpp/math_opt.h"
// IWYU pragma: friend "ortools/math_opt/cpp/.*"
#ifndef ORTOOLS_MATH_OPT_CPP_PARAMETERS_H_
#define ORTOOLS_MATH_OPT_CPP_PARAMETERS_H_
#include <cstdint>
#include <optional>
#include <string>
#include "absl/container/linked_hash_map.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "ortools/glop/parameters.pb.h" // IWYU pragma: export
#include "ortools/math_opt/cpp/enums.h" // IWYU pragma: export
#include "ortools/math_opt/parameters.pb.h"
#include "ortools/math_opt/solvers/cplex.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/gscip/gscip.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/gurobi.pb.h" // IWYU pragma: export
#include "ortools/math_opt/solvers/highs.pb.h" // IWYU pragma: export
#include "ortools/pdlp/solvers.pb.h" // IWYU pragma: export
#include "ortools/sat/sat_parameters.pb.h" // IWYU pragma: export
namespace operations_research {
namespace math_opt {
// The solvers supported by MathOpt.
enum class SolverType {
// 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.
kGscip = SOLVER_TYPE_GSCIP,
// Gurobi solver (third party).
//
// Supports LP, MIP, and nonconvex integer quadratic problems. Generally the
// fastest option, but has special licensing.
kGurobi = SOLVER_TYPE_GUROBI,
// Google's Glop solver.
//
// Supports LP with primal and dual simplex methods.
kGlop = SOLVER_TYPE_GLOP,
// 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.
kCpSat = SOLVER_TYPE_CP_SAT,
// Google's PDLP solver.
//
// Supports LP and convex diagonal quadratic objectives. Uses first order
// methods rather than simplex. Can solve very large problems.
kPdlp = SOLVER_TYPE_PDLP,
// 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 destroyed on the same thread as they are created or GLPK will
// crash. 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.
kGlpk = SOLVER_TYPE_GLPK,
// The Embedded Conic Solver (ECOS).
//
// Supports LP and SOCP problems. Uses interior point methods (barrier).
kEcos = SOLVER_TYPE_ECOS,
// The Splitting Conic Solver (SCS) (third party).
//
// Supports LP and SOCP problems. Uses a first-order method.
kScs = SOLVER_TYPE_SCS,
// The HiGHS Solver (third party).
//
// Supports LP and MIP problems (convex QPs are unimplemented).
kHighs = SOLVER_TYPE_HIGHS,
// MathOpt's reference implementation of a MIP solver.
//
// Slow/not recommended for production. Not an LP solver (no dual information
// returned).
kSantorini = SOLVER_TYPE_SANTORINI,
// Fico XPRESS solver (third party).
//
// Supports LP, MIP, and nonconvex integer quadratic problems.
// A fast option, but has special licensing.
kXpress = SOLVER_TYPE_XPRESS,
// IBM ILOG CPLEX solver (third party).
//
// Supports LP, MIP problems (other types are unimplemented).
// A fast option, but has special licensing.
kCplex = SOLVER_TYPE_CPLEX,
};
MATH_OPT_DEFINE_ENUM(SolverType, SOLVER_TYPE_UNSPECIFIED);
// Parses a flag of type SolverType.
//
// The expected values are the one returned by EnumToString().
bool AbslParseFlag(absl::string_view text, SolverType* value,
std::string* error);
// Unparses a flag of type SolverType.
//
// The returned values are the same as EnumToString().
std::string AbslUnparseFlag(SolverType value);
// Selects an algorithm for solving linear programs.
enum class LPAlgorithm {
// The (primal) simplex method. Typically can provide primal and dual
// solutions, primal/dual rays on primal/dual unbounded problems, and a basis.
kPrimalSimplex = LP_ALGORITHM_PRIMAL_SIMPLEX,
// The dual simplex method. Typically can provide primal and dual
// solutions, primal/dual rays on primal/dual unbounded problems, and a basis.
kDualSimplex = LP_ALGORITHM_DUAL_SIMPLEX,
// 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.
kBarrier = LP_ALGORITHM_BARRIER,
// 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.
kFirstOrder = LP_ALGORITHM_FIRST_ORDER,
};
MATH_OPT_DEFINE_ENUM(LPAlgorithm, LP_ALGORITHM_UNSPECIFIED);
// Parses a flag of type LPAlgorithm.
//
// The expected values are the one returned by EnumToString().
bool AbslParseFlag(absl::string_view text, LPAlgorithm* value,
std::string* error);
// Unparses a flag of type LPAlgorithm.
//
// The returned values are the same as EnumToString().
std::string AbslUnparseFlag(LPAlgorithm value);
// Effort level applied to an optional task while solving (see SolveParameters
// for use).
//
// Typically used as a std::optional<Emphasis>. It's used to configure a solver
// feature as follows:
// * If a solver doesn't support the feature, only nullopt will always be
// valid, any other setting will give an invalid argument error (some solvers
// may also accept kOff).
// * If the solver supports the feature:
// - When unset, the underlying default is used.
// - When the feature cannot be turned off, kOff will return an error.
// - If the feature is enabled by default, the solver default is typically
// mapped to kMedium.
// - If the feature is supported, kLow, kMedium, kHigh, and kVeryHigh will
// never give an error, and will map onto their best match.
enum class Emphasis {
kOff = EMPHASIS_OFF,
kLow = EMPHASIS_LOW,
kMedium = EMPHASIS_MEDIUM,
kHigh = EMPHASIS_HIGH,
kVeryHigh = EMPHASIS_VERY_HIGH
};
MATH_OPT_DEFINE_ENUM(Emphasis, EMPHASIS_UNSPECIFIED);
// Parses a flag of type Emphasis.
//
// The expected values are the one returned by EnumToString().
bool AbslParseFlag(absl::string_view text, Emphasis* value, std::string* error);
// Unparses a flag of type Emphasis.
//
// The returned values are the same as EnumToString().
std::string AbslUnparseFlag(Emphasis value);
// Gurobi specific parameters for solving. See
// https://www.gurobi.com/documentation/9.1/refman/parameters.html
// for a list of possible parameters.
//
// Example use:
// GurobiParameters gurobi;
// 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.
struct GurobiParameters {
// Parameter name-value pairs to set in insertion order.
absl::linked_hash_map<std::string, std::string> param_values;
GurobiParametersProto Proto() const;
static GurobiParameters FromProto(const GurobiParametersProto& proto);
bool empty() const { return param_values.empty(); }
};
// GLPK specific parameters for solving.
//
// Fields are optional to enable capturing user intention; if the user
// explicitly sets a value, then no generic solve parameters will overwrite this
// parameter. User specified solver specific parameters have priority over
// generic parameters.
struct GlpkParameters {
// 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::kPrimalSimplex. Same for a dual ray and
// LPAlgorithm::kDualSimplex.
//
// The computation involves the basis factorization to be available which may
// lead to extra computations/errors.
std::optional<bool> compute_unbound_rays_if_possible = std::nullopt;
GlpkParametersProto Proto() const;
static GlpkParameters FromProto(const GlpkParametersProto& proto);
};
// Xpress specific parameters for solving. See
// https://www.fico.com/fico-xpress-optimization/docs/latest/solver/optimizer/HTML/chapter7.html
// for a list of possible parameters (called "controls" in Xpress).
// In addition to all Xpress controls, the following special parameters are
// also supported:
// "EXPORT_MODEL"(string) If present then the low level Xpress model
// (the XPRSprob instance) is written to that file
// right before XPRSoptimize() is called. This can
// be useful for debugging.
// "FORCE_POSTSOLVE"(int) If set to a non-zero value then the low-level code
// will call XPRSpostsolve() right after calling
// XPRSoptimize(). If not set or set to zero then
// calling XPRSpostsolve() is delayed to the latest
// possible point in time to enable incremental
// solves.
// "STOP_AFTER_LP"(int) If set to a non-zero value then the solve will be
// stopped right after solving the root relaxation.
// This is the same as passing the ' l' (ell) flag
// to XPRSoptimize() and stops the process earlier
// than a limit like MAXNODE=0.
//
// Example use:
// XpressParameters xpress;
// xpress.param_values["BarIterLimit"] = "10";
//
// Parameters are applied in the following order:
// * Any parameters derived from ortools parameters (like LP algorithm).
// * param_values in iteration order (insertion order).
struct XpressParameters {
// Parameter name-value pairs to set in insertion order.
absl::linked_hash_map<std::string, std::string> param_values;
XpressParametersProto Proto() const;
static XpressParameters FromProto(const XpressParametersProto& proto);
bool empty() const { return param_values.empty(); }
};
struct CplexParameters {
absl::linked_hash_map<std::string, double> param_double_values;
absl::linked_hash_map<std::string, bool> param_bool_values;
absl::linked_hash_map<std::string, int32_t> param_int32_values;
absl::linked_hash_map<std::string, int64_t> param_int64_values;
absl::linked_hash_map<std::string, std::string> param_string_values;
CplexParametersProto Proto() const;
static CplexParameters FromProto(const CplexParametersProto& proto);
bool empty() const {
return param_double_values.empty() && param_bool_values.empty() &&
param_int32_values.empty() && param_int64_values.empty() &&
param_string_values.empty();
}
};
// Parameters to control a single solve.
//
// Contains both parameters common to all solvers, e.g. time_limit, and
// parameters for a specific solver, e.g. gscip. If a value is set in both
// common and solver specific fields, the solver specific setting is used.
//
// The common parameters that are optional and unset indicate that the solver
// default is used.
//
// Solver specific parameters for solvers other than the one in use are ignored.
//
// Parameters that depends on the model (e.g. branching priority is set for
// each variable) are passed in ModelSolveParametersProto.
struct SolveParameters {
// Enables printing the solver implementation traces. These traces are sent
// to the standard output stream.
//
// Note that if the user registers a message callback, then this parameter
// value is ignored and no traces are printed.
bool enable_output = false;
// Maximum time a solver should spend on the problem.
//
// This value is not a hard limit, solve time may slightly exceed this value.
// Always passed to the underlying solver, the solver default is not used.
absl::Duration time_limit = absl::InfiniteDuration();
// 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.
std::optional<int64_t> iteration_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.
std::optional<int64_t> node_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 termination reason kNoSolutionFound
// and with limit kCutoff 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.
std::optional<double> cutoff_limit;
// The solver stops early as soon as it finds a solution at least this good,
// with termination reason kFeasible and limit kObjective.
std::optional<double> objective_limit;
// The solver stops early as soon as it proves the best bound is at least this
// good, with termination reason kFeasible or kNoSolutionFound and limit
// kObjective.
//
// See the user guide for a comparison with cutoff_limit.
std::optional<double> best_bound_limit;
// The solver stops early after finding this many feasible solutions, with
// termination reason kFeasible and limit kSolution. Must be greater than
// zero if set. It is often used to 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, Xpress and SCIP, and for CP-SAT only with
// value 1.
std::optional<int32_t> solution_limit;
// If unset, use the solver default. If set, it must be >= 1.
std::optional<int32_t> threads;
// Seed for the pseudo-random number generator in the underlying
// solver. Note that all solvers use pseudo-random numbers to select things
// such as perturbation in the LP algorithm, for tie-break-up rules, and for
// heuristic fixings. Varying this can have a noticeable impact on solver
// behavior.
//
// Although all solvers have a concept of seeds, note that valid values
// depend on the actual solver.
// - Gurobi: [0:GRB_MAXINT] (which as of Gurobi 9.0 is 2x10^9).
// - GSCIP: [0:2147483647] (which is MAX_INT or kint32max or 2^31-1).
// - GLOP: [0:2147483647] (same as above)
// - Xpress: Any 32bit signed integer is allowed
// In all cases, the solver will receive a value equal to:
// MAX(0, MIN(MAX_VALID_VALUE_FOR_SOLVER, random_seed)).
std::optional<int32_t> random_seed;
// 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::kOptimal.
//
// Must be >= 0 if set.
//
// See also relative_gap_tolerance.
std::optional<double> absolute_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::kOptimal.
//
// Must be >= 0 if set.
//
// See also absolute_gap_tolerance.
std::optional<double> relative_gap_tolerance;
// Maintain up to `solution_pool_size` solutions while searching. The solution
// pool generally has two functions:
// (1) For solvers that can return more than one solution, this limits how
// many solutions will be returned.
// (2) Some solvers may run heuristics using solutions from the solution
// pool, so changing this value may affect the algorithm's path.
// To force the solver to fill the solution pool, e.g. with the n best
// solutions, requires further, solver specific configuration.
std::optional<int32_t> solution_pool_size;
// The algorithm for solving a linear program. If nullopt, 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).
std::optional<LPAlgorithm> lp_algorithm;
// Effort on simplifying the problem before starting the main algorithm, or
// the solver default effort level if unset.
std::optional<Emphasis> presolve;
// Effort on getting a stronger LP relaxation (MIP only) or the solver default
// effort level if unset.
//
// NOTE: disabling cuts may prevent callbacks from having a chance to add cuts
// at MIP_NODE, this behavior is solver specific.
std::optional<Emphasis> cuts;
// Effort in finding feasible solutions beyond those encountered in the
// complete search procedure (MIP only), or the solver default effort level if
// unset.
std::optional<Emphasis> heuristics;
// Effort in rescaling the problem to improve numerical stability, or the
// solver default effort level if unset.
std::optional<Emphasis> scaling;
GScipParameters gscip;
GurobiParameters gurobi;
glop::GlopParameters glop;
sat::SatParameters cp_sat;
pdlp::PrimalDualHybridGradientParams pdlp;
GlpkParameters glpk;
HighsOptionsProto highs;
XpressParameters xpress;
CplexParameters cplex;
SolveParametersProto Proto() const;
static absl::StatusOr<SolveParameters> FromProto(
const SolveParametersProto& proto);
};
bool AbslParseFlag(absl::string_view text, SolveParameters* solve_parameters,
std::string* error);
std::string AbslUnparseFlag(SolveParameters solve_parameters);
} // namespace math_opt
} // namespace operations_research
#endif // ORTOOLS_MATH_OPT_CPP_PARAMETERS_H_