forked from rte-france/or-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parameters.proto
487 lines (415 loc) · 23.9 KB
/
parameters.proto
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
// Copyright 2010-2022 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.
// Contains the definitions for all the GLOP algorithm parameters and their
// default values.
//
// TODO(user): Make the above statement true by moving all algorithm parameters
// flags here.
syntax = "proto2";
package operations_research.glop;
option java_package = "com.google.ortools.glop";
option java_multiple_files = true;
option csharp_namespace = "Google.OrTools.Glop";
// next id = 70
message GlopParameters {
// Supported algorithms for scaling:
// EQUILIBRATION - progressive scaling by row and column norms until the
// marginal difference passes below a threshold.
// LINEAR_PROGRAM - EXPERIMENTAL: finding optimal scale factors using a linear
// program in the log scale.
enum ScalingAlgorithm {
DEFAULT = 0;
EQUILIBRATION = 1;
LINEAR_PROGRAM = 2;
}
// Like a Boolean with an extra value to let the algorithm decide what is the
// best choice.
enum SolverBehavior {
ALWAYS_DO = 0;
NEVER_DO = 1;
LET_SOLVER_DECIDE = 2;
}
// General strategy used during pricing.
enum PricingRule {
// Strategy using only the reduced cost of a variable.
//
// Note that compared to a textbook rule, we normalize the reduced cost of a
// variable using the norm of the associated column. This improves quite a
// bit the rule at almost no extra complexity. See the first paper from
// Ping-Qi Pan cited in primal_edge_norms.h.
DANTZIG = 0;
// Normalize the reduced costs by the norm of the edges. Since computing
// norms at each step is too expensive, reduced costs and norms are
// updated iteratively from one iteration to the next.
STEEPEST_EDGE = 1;
// Normalize the reduced costs by an approximation of the norm of the edges.
// This should offer a good tradeoff between steepest edge and speed.
DEVEX = 2;
}
// Heuristics to use in the primal simplex to remove fixed slack variables
// from the initial basis.
enum InitialBasisHeuristic {
// Leave the fixed slack variables in the basis.
NONE = 0;
// Use the heuristic described in:
// Robert E. Bixby, "Implementing the Simplex Method: The Initial Basis"
// ORSA Jounal on Computing, Vol. 4, No. 3, Summer 1992.
// http://joc.journal.informs.org/content/4/3/267.abstract
//
// It requires use_scaling to be true, otherwise it behaves like NONE.
BIXBY = 1;
// Replace the fixed columns while keeping the initial basis triangular. The
// heuristic to select which column to use first is similar to the one used
// for BIXBY. This algorithm is similar to the "advanced initial basis"
// GLPK uses by default. Both algorithm produce a triangular initial basis,
// however the heuristics used are not exactly the same.
TRIANGULAR = 2;
// Use a version of Maros's triangular feasibility crash
// https://books.google.fr/books?isbn=1461502578
// Chapter 9.8.2.1
MAROS = 3;
}
optional ScalingAlgorithm scaling_method = 57 [default = EQUILIBRATION];
// PricingRule to use during the feasibility phase.
optional PricingRule feasibility_rule = 1 [default = STEEPEST_EDGE];
// PricingRule to use during the optimization phase.
optional PricingRule optimization_rule = 2 [default = STEEPEST_EDGE];
// We estimate the factorization accuracy of B during each pivot by using
// the fact that we can compute the pivot coefficient in two ways:
// - From direction[leaving_row].
// - From update_row[entering_column].
// If the two values have a relative difference above this threshold, we
// trigger a refactorization.
optional double refactorization_threshold = 6 [default = 1e-9];
// We estimate the accuracy of the iteratively computed reduced costs. If
// it falls below this threshold, we reinitialize them from scratch. Note
// that such an operation is pretty fast, so we can use a low threshold.
// It is important to have a good accuracy here (better than the
// dual_feasibility_tolerance below) to be sure of the sign of such a cost.
optional double recompute_reduced_costs_threshold = 8 [default = 1e-8];
// Note that the threshold is a relative error on the actual norm (not the
// squared one) and that edge norms are always greater than 1. Recomputing
// norms is a really expensive operation and a large threshold is ok since
// this doesn't impact directly the solution but just the entering variable
// choice.
optional double recompute_edges_norm_threshold = 9 [default = 100.0];
// The three following parameters correspond to the tolerance epsilon 1,2 and
// 3 described in Chvatal p. 115 in the section "Zero Tolerances".
// This tolerance indicates by how much we allow the variable values to go out
// of bounds and still consider the current solution primal-feasible. We also
// use the same tolerance for the error A.x - b. Note that the two errors are
// closely related if A is scaled in such a way that the greatest coefficient
// magnitude on each column is 1.0.
//
// This is also simply called feasibility tolerance in other solvers.
optional double primal_feasibility_tolerance = 10 [default = 1e-8];
// Variables whose reduced costs have an absolute value smaller than this
// tolerance are not considered as entering candidates. That is they do not
// take part in deciding whether a solution is dual-feasible or not.
//
// Note that this value can temporarily increase during the execution of the
// algorithm if the estimated precision of the reduced costs is higher than
// this tolerance. Note also that we scale the costs (in the presolve step) so
// that the cost magnitude range contains one.
//
// This is also known as the optimality tolerance in other solvers.
optional double dual_feasibility_tolerance = 11 [default = 1e-8];
// During the primal simplex (resp. dual simplex), the coefficients of the
// direction (resp. update row) with a magnitude lower than this threshold are
// not considered during the ratio test. This tolerance is related to the
// precision at which a Solve() involving the basis matrix can be performed.
//
// TODO(user): Automatically increase it when we detect that the precision
// of the Solve() is worse than this.
optional double ratio_test_zero_threshold = 12 [default = 1e-9];
// This impacts the ratio test and indicates by how much we allow a basic
// variable value that we move to go out of bounds. The value should be in
// [0.0, 1.0) and should be interpreted as a ratio of the
// primal_feasibility_tolerance. Setting this to 0.0 basically disables the
// Harris ratio test while setting this too close to 1.0 will make it
// difficult to keep the variable values inside their bounds modulo the
// primal_feasibility_tolerance.
//
// Note that the same comment applies to the dual simplex ratio test. There,
// we allow the reduced costs to be of an infeasible sign by as much as this
// ratio times the dual_feasibility_tolerance.
optional double harris_tolerance_ratio = 13 [default = 0.5];
// When we choose the leaving variable, we want to avoid small pivot because
// they are the less precise and may cause numerical instabilities. For a
// pivot under this threshold times the infinity norm of the direction, we try
// various countermeasures in order to avoid using it.
optional double small_pivot_threshold = 14 [default = 1e-6];
// We never follow a basis change with a pivot under this threshold.
optional double minimum_acceptable_pivot = 15 [default = 1e-6];
// In order to increase the sparsity of the manipulated vectors, floating
// point values with a magnitude smaller than this parameter are set to zero
// (only in some places). This parameter should be positive or zero.
optional double drop_tolerance = 52 [default = 1e-14];
// Whether or not we scale the matrix A so that the maximum coefficient on
// each line and each column is 1.0.
optional bool use_scaling = 16 [default = true];
// This is only used if use_scaling is true. After the scaling is done, we
// also scale the objective by a constant factor. This is important because
// scaling the cost has a direct influence on the meaning of the
// dual_feasibility_tolerance. Because we usually use a fixed tolerance, the
// objective must be well scaled to make sense.
enum CostScalingAlgorithm {
// Leave the cost as is.
NO_COST_SCALING = 0;
// This is the most defensive option. It makes sure that
// [min_cost_magnitude, max_cost_magnitude] contains 1.0, and if not, it
// makes the closest magnitude bound equal to one.
CONTAIN_ONE_COST_SCALING = 1;
// Make the mean of the non-zero costs equals to one.
MEAN_COST_SCALING = 2;
// Make the median of the non-zero costs equals to one.
MEDIAN_COST_SCALING = 3;
}
optional CostScalingAlgorithm cost_scaling = 60
[default = CONTAIN_ONE_COST_SCALING];
// What heuristic is used to try to replace the fixed slack columns in the
// initial basis of the primal simplex.
optional InitialBasisHeuristic initial_basis = 17 [default = TRIANGULAR];
// Whether or not we keep a transposed version of the matrix A to speed-up the
// pricing at the cost of extra memory and the initial tranposition
// computation.
optional bool use_transposed_matrix = 18 [default = true];
// Number of iterations between two basis refactorizations. Note that various
// conditions in the algorithm may trigger a refactorization before this
// period is reached. Set this to 0 if you want to refactorize at each step.
optional int32 basis_refactorization_period = 19 [default = 64];
// If this is true, then basis_refactorization_period becomes a lower bound on
// the number of iterations between two refactorization (provided there is no
// numerical accuracy issues). Depending on the estimated time to refactorize
// vs the extra time spend in each solves because of the LU update, we try to
// balance the two times.
optional bool dynamically_adjust_refactorization_period = 63 [default = true];
// Whether or not we solve the dual of the given problem.
// With a value of auto, the algorithm decide which approach is probably the
// fastest depending on the problem dimensions (see dualizer_threshold).
optional SolverBehavior solve_dual_problem = 20 [default = LET_SOLVER_DECIDE];
// When solve_dual_problem is LET_SOLVER_DECIDE, take the dual if the number
// of constraints of the problem is more than this threshold times the number
// of variables.
optional double dualizer_threshold = 21 [default = 1.5];
// When the problem status is OPTIMAL, we check the optimality using this
// relative tolerance and change the status to IMPRECISE if an issue is
// detected.
//
// The tolerance is "relative" in the sense that our thresholds are:
// - tolerance * max(1.0, abs(bound)) for crossing a given bound.
// - tolerance * max(1.0, abs(cost)) for an infeasible reduced cost.
// - tolerance for an infeasible dual value.
optional double solution_feasibility_tolerance = 22 [default = 1e-6];
// If true, then when the solver returns a solution with an OPTIMAL status,
// we can guarantee that:
// - The primal variable are in their bounds.
// - The dual variable are in their bounds.
// - If we modify each component of the right-hand side a bit and each
// component of the objective function a bit, then the pair (primal values,
// dual values) is an EXACT optimal solution of the perturbed problem.
// - The modifications above are smaller than the associated tolerances as
// defined in the comment for solution_feasibility_tolerance (*).
//
// (*): This is the only place where the guarantee is not tight since we
// compute the upper bounds with scalar product of the primal/dual
// solution and the initial problem coefficients with only double precision.
//
// Note that whether or not this option is true, we still check the
// primal/dual infeasibility and objective gap. However if it is false, we
// don't move the primal/dual values within their bounds and leave them
// untouched.
optional bool provide_strong_optimal_guarantee = 24 [default = true];
// If true, the internal API will change the return status to imprecise if the
// solution does not respect the internal tolerances.
optional bool change_status_to_imprecise = 58 [default = true];
// When the solution of phase II is imprecise, we re-run the phase II with the
// opposite algorithm from that imprecise solution (i.e., if primal or dual
// simplex was used, we use dual or primal simplex, respectively). We repeat
// such re-optimization until the solution is precise, or we hit this limit.
optional double max_number_of_reoptimizations = 56 [default = 40];
// Threshold for LU-factorization: for stability reasons, the magnitude of the
// chosen pivot at a given step is guaranteed to be greater than this
// threshold times the maximum magnitude of all the possible pivot choices in
// the same column. The value must be in [0,1].
optional double lu_factorization_pivot_threshold = 25 [default = 0.01];
// Maximum time allowed in seconds to solve a problem.
optional double max_time_in_seconds = 26 [default = inf];
// Maximum deterministic time allowed to solve a problem. The deterministic
// time is more or less correlated to the running time, and its unit should
// be around the second (at least on a Xeon(R) CPU E5-1650 v2 @ 3.50GHz).
//
// TODO(user): Improve the correlation.
optional double max_deterministic_time = 45 [default = inf];
// Maximum number of simplex iterations to solve a problem.
// A value of -1 means no limit.
optional int64 max_number_of_iterations = 27 [default = -1];
// How many columns do we look at in the Markowitz pivoting rule to find
// a good pivot. See markowitz.h.
optional int32 markowitz_zlatev_parameter = 29 [default = 3];
// If a pivot magnitude is smaller than this during the Markowitz LU
// factorization, then the matrix is assumed to be singular. Note that
// this is an absolute threshold and is not relative to the other possible
// pivots on the same column (see lu_factorization_pivot_threshold).
optional double markowitz_singularity_threshold = 30 [default = 1e-15];
// Whether or not we use the dual simplex algorithm instead of the primal.
optional bool use_dual_simplex = 31 [default = false];
// During incremental solve, let the solver decide if it use the primal or
// dual simplex algorithm depending on the current solution and on the new
// problem. Note that even if this is true, the value of use_dual_simplex
// still indicates the default algorithm that the solver will use.
optional bool allow_simplex_algorithm_change = 32 [default = false];
// Devex weights will be reset to 1.0 after that number of updates.
optional int32 devex_weights_reset_period = 33 [default = 150];
// Whether or not we use advanced preprocessing techniques.
optional bool use_preprocessing = 34 [default = true];
// Whether or not to use the middle product form update rather than the
// standard eta LU update. The middle form product update should be a lot more
// efficient (close to the Forrest-Tomlin update, a bit slower but easier to
// implement). See for more details:
// Qi Huangfu, J. A. Julian Hall, "Novel update techniques for the revised
// simplex method", 28 january 2013, Technical Report ERGO-13-0001
// http://www.maths.ed.ac.uk/hall/HuHa12/ERGO-13-001.pdf
optional bool use_middle_product_form_update = 35 [default = true];
// Whether we initialize devex weights to 1.0 or to the norms of the matrix
// columns.
optional bool initialize_devex_with_column_norms = 36 [default = true];
// Whether or not we exploit the singleton columns already present in the
// problem when we create the initial basis.
optional bool exploit_singleton_column_in_initial_basis = 37 [default = true];
// Like small_pivot_threshold but for the dual simplex. This is needed because
// the dual algorithm does not interpret this value in the same way.
// TODO(user): Clean this up and use the same small pivot detection.
optional double dual_small_pivot_threshold = 38 [default = 1e-4];
// A floating point tolerance used by the preprocessors. This is used for
// things like detecting if two columns/rows are proportional or if an
// interval is empty.
//
// Note that the preprocessors also use solution_feasibility_tolerance() to
// detect if a problem is infeasible.
optional double preprocessor_zero_tolerance = 39 [default = 1e-9];
// The solver will stop as soon as it has proven that the objective is smaller
// than objective_lower_limit or greater than objective_upper_limit. Depending
// on the simplex algorithm (primal or dual) and the optimization direction,
// note that only one bound will be used at the time.
//
// Important: The solver does not add any tolerances to these values, and as
// soon as the objective (as computed by the solver, so with some imprecision)
// crosses one of these bounds (strictly), the search will stop. It is up to
// the client to add any tolerance if needed.
optional double objective_lower_limit = 40 [default = -inf];
optional double objective_upper_limit = 41 [default = inf];
// During a degenerate iteration, the more conservative approach is to do a
// step of length zero (while shifting the bound of the leaving variable).
// That is, the variable values are unchanged for the primal simplex or the
// reduced cost are unchanged for the dual simplex. However, instead of doing
// a step of length zero, it seems to be better on degenerate problems to do a
// small positive step. This is what is recommanded in the EXPAND procedure
// described in:
// P. E. Gill, W. Murray, M. A. Saunders, and M. H. Wright. "A practical anti-
// cycling procedure for linearly constrained optimization".
// Mathematical Programming, 45:437\u2013474, 1989.
//
// Here, during a degenerate iteration we do a small positive step of this
// factor times the primal (resp. dual) tolerance. In the primal simplex, this
// may effectively push variable values (very slightly) further out of their
// bounds (resp. reduced costs for the dual simplex).
//
// Setting this to zero reverts to the more conservative approach of a zero
// step during degenerate iterations.
optional double degenerate_ministep_factor = 42 [default = 0.01];
// At the beginning of each solve, the random number generator used in some
// part of the solver is reinitialized to this seed. If you change the random
// seed, the solver may make different choices during the solving process.
// Note that this may lead to a different solution, for example a different
// optimal basis.
//
// For some problems, the running time may vary a lot depending on small
// change in the solving algorithm. Running the solver with different seeds
// enables to have more robust benchmarks when evaluating new features.
//
// Also note that the solver is fully deterministic: two runs of the same
// binary, on the same machine, on the exact same data and with the same
// parameters will go through the exact same iterations. If they hit a time
// limit, they might of course yield different results because one will have
// advanced farther than the other.
optional int32 random_seed = 43 [default = 1];
// Number of threads in the OMP parallel sections. If left to 1, the code will
// not create any OMP threads and will remain single-threaded.
optional int32 num_omp_threads = 44 [default = 1];
// When this is true, then the costs are randomly perturbed before the dual
// simplex is even started. This has been shown to improve the dual simplex
// performance. For a good reference, see Huangfu Q (2013) "High performance
// simplex solver", Ph.D, dissertation, University of Edinburgh.
optional bool perturb_costs_in_dual_simplex = 53 [default = false];
// We have two possible dual phase I algorithms. Both work on an LP that
// minimize the sum of dual infeasiblities. One use dedicated code (when this
// param is true), the other one use exactly the same code as the dual phase
// II but on an auxiliary problem where the variable bounds of the original
// problem are changed.
//
// TODO(user): For now we have both, but ideally the non-dedicated version
// will win since it is a lot less code to maintain.
optional bool use_dedicated_dual_feasibility_algorithm = 62 [default = true];
// The magnitude of the cost perturbation is given by
// RandomIn(1.0, 2.0) * (
// relative_cost_perturbation * cost
// + relative_max_cost_perturbation * max_cost);
optional double relative_cost_perturbation = 54 [default = 1e-5];
optional double relative_max_cost_perturbation = 55 [default = 1e-7];
// If our upper bound on the condition number of the initial basis (from our
// heurisitic or a warm start) is above this threshold, we revert to an all
// slack basis.
optional double initial_condition_number_threshold = 59 [default = 1e50];
// If true, logs the progress of a solve to LOG(INFO). Note that the same
// messages can also be turned on by displaying logs at level 1 for the
// relevant files.
optional bool log_search_progress = 61 [default = false];
// If true, logs will be displayed to stdout instead of using Google log info.
optional bool log_to_stdout = 66 [default = true];
// If the starting basis contains FREE variable with bounds, we will move
// any such variable to their closer bounds if the distance is smaller than
// this parameter.
//
// The starting statuses can contains FREE variables with bounds, if a user
// set it like this externally. Also, any variable with an initial BASIC
// status that was not kept in the initial basis is marked as FREE before this
// step is applied.
//
// Note that by default a FREE variable is assumed to be zero unless a
// starting value was specified via SetStartingVariableValuesForNextSolve().
//
// Note that, at the end of the solve, some of these FREE variable with bounds
// and an interior point value might still be left in the final solution.
// Enable push_to_vertex to clean these up.
optional double crossover_bound_snapping_distance = 64 [default = inf];
// If the optimization phases finishes with super-basic variables (i.e.,
// variables that either 1) have bounds but are FREE in the basis, or 2) have
// no bounds and are FREE in the basis at a nonzero value), then run a "push"
// phase to push these variables to bounds, obtaining a vertex solution. Note
// this situation can happen only if a starting value was specified via
// SetStartingVariableValuesForNextSolve().
optional bool push_to_vertex = 65 [default = true];
// If presolve runs, include the pass that detects implied free variables.
optional bool use_implied_free_preprocessor = 67 [default = true];
// Any finite values in the input LP must be below this threshold, otherwise
// the model will be reported invalid. This is needed to avoid floating point
// overflow when evaluating bounds * coeff for instance. In practice, users
// shouldn't use super large values in an LP. With the default threshold, even
// evaluating large constraint with variables at their bound shouldn't cause
// any overflow.
optional double max_valid_magnitude = 199 [default = 1e30];
// On some problem like stp3d or pds-100 this makes a huge difference in
// speed and number of iterations of the dual simplex.
optional bool dual_price_prioritize_norm = 69 [default = false];
}