Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
solve_log.proto
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// These proto messages are for collecting solve statistics, e.g., during
15// experiments.
16
17syntax = "proto2";
18
19package operations_research.pdlp;
20
21option java_package = "com.google.ortools.pdlp";
22option java_multiple_files = true;
23option csharp_namespace = "Google.OrTools.PDLP";
24
25import "ortools/pdlp/solvers.proto";
26
27// Easy-to-compute statistics for the quadratic program.
28message QuadraticProgramStats {
29 optional int64 num_variables = 1;
30 optional int64 num_constraints = 2;
31
32 // Minimum row and column infinity norms of the constraint matrix. All-zero
33 // rows and columns are excluded. If the constraint matrix contains no nonzero
34 // entries, the values returned are 0.0.
35 optional double constraint_matrix_col_min_l_inf_norm = 3;
36 optional double constraint_matrix_row_min_l_inf_norm = 4;
37
38 // The number of (finite) nonzero entries in the constraint matrix.
39 optional int64 constraint_matrix_num_nonzeros = 5;
40
41 // Max/min/mean/l2_norm of absolute values of (finite) elements in constraint
42 // matrix. Explicit zeros are included in the mean, but excluded from the min.
43 // Note that the maximum absolute value is also equal to the maximal row and
44 // column infinity norms of the constraint matrix. If the constraint matrix is
45 // empty, the values returned are 0.0 for the maximum, minimum, and l2_norm,
46 // and NaN for the average.
47 optional double constraint_matrix_abs_max = 6;
48 optional double constraint_matrix_abs_min = 7;
49 optional double constraint_matrix_abs_avg = 8;
50 optional double constraint_matrix_l2_norm = 25;
51
52 // Statistics of the combined vector of the constraint lower and upper bounds.
53 // Given parallel lower and upper bounds vectors, the "combined bounds" vector
54 // takes the maximum absolute value of each pair of bounds, ignoring all non-
55 // finite values. The comment in solvers.proto:TerminationCriteria provides an
56 // example of the combined bounds vector. The min is over the nonzero combined
57 // bounds. If there are no constraints, the values returned are 0 for the
58 // maximum, minimum, and l2 norm and NaN for the average.
59 optional double combined_bounds_max = 9;
60 optional double combined_bounds_min = 10;
61 optional double combined_bounds_avg = 11;
62 optional double combined_bounds_l2_norm = 24;
63
64 // Statistics of the combined vector of the variable lower and upper bounds.
65 // See the comment before `combined_bounds_max` for a description of the
66 // "combined bounds" vector. The min is over the nonzero combined bounds. If
67 // there are no variables, the values returned are 0 for the maximum, minimum,
68 // and l2 norm and NaN for the average.
69 optional double combined_variable_bounds_max = 28;
70 optional double combined_variable_bounds_min = 29;
71 optional double combined_variable_bounds_avg = 30;
72 optional double combined_variable_bounds_l2_norm = 31;
73
74 // Number of finite variable bound gaps, which are the elementwise difference
75 // between the upper and lower bounds on primal feasible solutions.
76 optional int64 variable_bound_gaps_num_finite = 12;
77
78 // Max/min/mean/l2_norm over all finite variable bound gaps. The min excludes
79 // zero bound gaps (i.e., fixed variables). When there are no finite gaps, the
80 // values returned are 0 for the maximum, minimum, and l2_norm, and NaN for
81 // the average.
82 optional double variable_bound_gaps_max = 13;
83 optional double variable_bound_gaps_min = 14;
84 optional double variable_bound_gaps_avg = 15;
85 optional double variable_bound_gaps_l2_norm = 26;
86
87 // Statistics of the objective vector. The min is over the nonzero terms.
88 optional double objective_vector_abs_max = 16;
89 optional double objective_vector_abs_min = 17;
90 optional double objective_vector_abs_avg = 18;
91 optional double objective_vector_l2_norm = 23;
92
93 optional int64 objective_matrix_num_nonzeros = 19;
94
95 // Max/min/mean/l2_norm of absolute values of elements of the objective
96 // matrix. The min is over nonzero terms. If the objective matrix is empty,
97 // the returned values are 0.0, 0.0, NaN, and 0.0 respectively.
98 optional double objective_matrix_abs_max = 20;
99 optional double objective_matrix_abs_min = 21;
100 optional double objective_matrix_abs_avg = 22;
101 optional double objective_matrix_l2_norm = 27;
102}
103
104// Specifies whether a restart was performed on a given iteration.
105enum RestartChoice {
106 RESTART_CHOICE_UNSPECIFIED = 0;
107 // No restart on this iteration.
108 RESTART_CHOICE_NO_RESTART = 1;
109 // The weighted average of iterates is cleared and reset to the current point.
110 // Note that from a mathematical perspective this can be equivalently viewed
111 // as restarting the algorithm but picking the restart point to be the current
112 // iterate.
113 RESTART_CHOICE_WEIGHTED_AVERAGE_RESET = 2;
114 // The algorithm is restarted at the average of iterates since the last
115 // restart.
116 RESTART_CHOICE_RESTART_TO_AVERAGE = 3;
117}
118
119// Identifies the type of point used to compute the fields in a given proto; see
120// ConvergenceInformation and InfeasibilityInformation.
121enum PointType {
122 POINT_TYPE_UNSPECIFIED = 0;
123 // Current iterate (x_k, y_k).
124 POINT_TYPE_CURRENT_ITERATE = 1;
125 // Difference of iterates (x_{k+1} - x_k, y_{k+1} - y_k).
126 POINT_TYPE_ITERATE_DIFFERENCE = 2;
127 // Average of iterates since the last restart.
128 POINT_TYPE_AVERAGE_ITERATE = 3;
129 // There is no corresponding point.
130 POINT_TYPE_NONE = 4;
131 // Output of presolver.
132 POINT_TYPE_PRESOLVER_SOLUTION = 5;
133 // Combined solution from primal and dual feasibility polishing.
134 POINT_TYPE_FEASIBILITY_POLISHING_SOLUTION = 6;
135}
136
137// Information measuring how close a candidate is to establishing feasibility
138// and optimality; see also TerminationCriteria.
139message ConvergenceInformation {
140 // Type of the candidate point described by this ConvergenceInformation.
141 optional PointType candidate_type = 1;
142
143 // The primal objective. The primal need not be feasible.
144 optional double primal_objective = 2;
145
146 // The dual objective. The dual need not be feasible. The dual objective
147 // includes the contributions from reduced costs.
148 // NOTE: The definition of dual_objective changed in OR-tools version 9.8.
149 // See
150 // https://developers.google.com/optimization/lp/pdlp_math#reduced_costs_dual_residuals_and_the_corrected_dual_objective
151 // for details.
152 optional double dual_objective = 3;
153
154 // If possible (e.g., when all primal variables have lower and upper bounds),
155 // a correct dual bound. The value is negative infinity if no corrected dual
156 // bound is available.
157 optional double corrected_dual_objective = 4;
158
159 // The maximum violation of any primal constraint, i.e., the l_∞ norm of the
160 // violations.
161 optional double l_inf_primal_residual = 5;
162
163 // The l_2 norm of the violations of primal constraints.
164 optional double l2_primal_residual = 6;
165
166 // The maximum relative violation of any primal constraint, with an absolute
167 // offset, i.e., the l_∞ norm of [violation / (eps_ratio + |bound|)] where
168 // eps_ratio = eps_optimal_primal_residual_absolute
169 // / eps_optimal_primal_residual_relative
170 // and bound is the violated bound.
171 optional double l_inf_componentwise_primal_residual = 24;
172
173 // The maximum violation of any dual constraint, i.e., the l_∞ norm of the
174 // violations.
175 optional double l_inf_dual_residual = 7;
176
177 // The l_2 norm of the violations of dual constraints.
178 optional double l2_dual_residual = 8;
179
180 // The maximum relative violation of any dual constraint, with an absolute
181 // offset, i.e., the l_∞ norm of [violation / (eps_ratio + |objective|)] where
182 // eps_ratio = eps_optimal_dual_residual_absolute
183 // / eps_optimal_dual_residual_relative
184 optional double l_inf_componentwise_dual_residual = 25;
185
186 // The maximum absolute value of the primal variables, i.e., the l_∞ norm.
187 // This is useful to detect when the primal iterates are diverging. Divergence
188 // of the primal variables could be an algorithmic issue, or indicate that the
189 // dual is infeasible.
190 optional double l_inf_primal_variable = 14;
191
192 // The l_2 norm of the primal variables.
193 optional double l2_primal_variable = 15;
194
195 // The maximum absolute value of the dual variables, i.e., the l_∞ norm. This
196 // is useful to detect when the dual iterates are diverging. Divergence of the
197 // dual variables could be an algorithmic issue, or indicate the primal is
198 // infeasible.
199 optional double l_inf_dual_variable = 16;
200
201 // The l_2 norm of the dual variables.
202 optional double l2_dual_variable = 17;
203
204 reserved 9, 10, 11, 12, 13, 18, 19, 20, 21, 22, 23;
205}
206
207// Information measuring how close a point is to establishing primal or dual
208// infeasibility (i.e. has no solution); see also TerminationCriteria.
209message InfeasibilityInformation {
210 // Let x_ray be the algorithm's estimate of the primal extreme ray where x_ray
211 // is a vector that satisfies the sign constraints for a ray, scaled such that
212 // its infinity norm is one (the sign constraints are the variable bound
213 // constraints, with all finite bounds mapped to zero). A simple and typical
214 // choice of x_ray is x_ray = x / | x |_∞ where x is the current primal
215 // iterate projected onto the primal ray sign constraints. For this value
216 // compute the maximum absolute error in the primal linear program with the
217 // right hand side set to zero.
218 optional double max_primal_ray_infeasibility = 1;
219
220 // The value of the linear part of the primal objective (ignoring additive
221 // constants) evaluated at x_ray, i.e., c' * x_ray where c is the objective
222 // coefficient vector.
223 optional double primal_ray_linear_objective = 2;
224
225 // The l_∞ norm of the vector resulting from taking the quadratic matrix from
226 // primal objective and multiplying it by the primal variables. For linear
227 // programming problems this is zero.
228 optional double primal_ray_quadratic_norm = 3;
229
230 // Let (y_ray, r_ray) be the algorithm's estimate of the dual and reduced cost
231 // extreme ray where (y_ray, r_ray) is a vector (satisfying the dual variable
232 // constraints) scaled such that its infinity norm is one. A simple and
233 // typical choice of y_ray is (y_ray, r_ray) = (y, r) / max(| y |_∞, | r |_∞)
234 // where y is the current dual iterate and r is the current dual reduced
235 // costs. Consider the quadratic program we are solving but with the objective
236 // (both quadratic and linear terms) set to zero. This forms a linear program
237 // (label this linear program (1)) with no objective. Take the dual of (1) and
238 // compute the maximum absolute value of the constraint error for
239 // (y_ray, r_ray) to obtain the value of max_dual_ray_infeasibility.
240 optional double max_dual_ray_infeasibility = 4;
241
242 // The objective of the linear program labeled (1) in the previous paragraph.
243 optional double dual_ray_objective = 5;
244
245 // Type of the point used to compute the InfeasibilityInformation.
246 optional PointType candidate_type = 6;
247
248 reserved 7, 8;
249}
250
251message PointMetadata {
252 // Type of the point that this metadata corresponds to.
253 optional PointType point_type = 1;
254
255 // Projections of the primal solution onto random planes.
256 repeated double random_primal_projections = 2 [packed = true];
257
258 // Projections of the dual solution onto random planes.
259 repeated double random_dual_projections = 3 [packed = true];
260
261 // The number of primal variables that are not at their bounds.
262 optional int64 active_primal_variable_count = 4;
263
264 // The number of dual variables that are not at their bounds.
265 optional int64 active_dual_variable_count = 5;
266
267 // The number of primal variables that have a different bound status than they
268 // did at the last restart.
269 optional int64 active_primal_variable_change = 6;
270
271 // The number of dual variables that have a different bound status than they
272 // did at the last restart.
273 optional int64 active_dual_variable_change = 7;
274}
275
276// All values in IterationStats assume that the primal quadratic program is a
277// minimization problem and the dual is a maximization problem. Problems should
278// be transformed to this form if they are not already in this form. The dual
279// vector is defined to be the vector of multipliers on the linear constraints,
280// that is, excluding dual multipliers on variable bounds (reduced costs).
281message IterationStats {
282 // The iteration number at which these stats were recorded. By convention,
283 // iteration counts start at 1, and the stats correspond to the solution
284 // *after* the iteration. Therefore stats from iteration 0 are the stats at
285 // the starting point.
286 optional int32 iteration_number = 1;
287
288 // A set of statistics measuring how close a point is to establishing primal
289 // and dual feasibility and optimality. This field is repeated since there
290 // might be several different points that are considered.
291 repeated ConvergenceInformation convergence_information = 2;
292
293 // A set of statistics measuring how close a point is to establishing primal
294 // or dual infeasibility (i.e., has no solution). This field is repeated since
295 // there might be several different points that could establish infeasibility.
296 repeated InfeasibilityInformation infeasibility_information = 3;
297
298 // Auxiliary statistics for each type of point.
299 repeated PointMetadata point_metadata = 11;
300
301 // The cumulative number of passes through the KKT matrix since the start of
302 // the solve. One pass is a multply by the constraint matrix, its transpose
303 // and the matrix that defines the quadratic part of the objective.
304 //
305 // For example, each iteration of mirror saddle prox contributes 2.0 to this
306 // sum. This is a float because it can include fractional passes through the
307 // data. For example, in an active set method we may only use a submatrix with
308 // 20% of the nonzeros of the KKT matrix at each iteration in which case 0.2
309 // would be added to the total.
310 optional double cumulative_kkt_matrix_passes = 4;
311
312 // The total number of rejected steps (e.g., within a line search procedure)
313 // since the start of the solve.
314 optional int32 cumulative_rejected_steps = 5;
315
316 // The amount of time passed since we started solving the problem (see solver
317 // log `solve_time_sec` which records total time).
318 optional double cumulative_time_sec = 6;
319
320 // The kind of restart that occurred at this iteration, or NO_RESTART if a
321 // restart did not occur.
322 optional RestartChoice restart_used = 7;
323
324 // Step size used at this iteration. Note that the step size used for the
325 // primal update is step_size / primal_weight, while the one used for the dual
326 // update is step_size * primal_weight.
327 optional double step_size = 8;
328
329 // Primal weight controlling the relation between primal and dual step sizes.
330 // See field 'step_size' for a detailed description.
331 optional double primal_weight = 9;
332
333 reserved 10;
334}
335
336enum TerminationReason {
337 TERMINATION_REASON_UNSPECIFIED = 0;
338 TERMINATION_REASON_OPTIMAL = 1;
339 // Note in this situation the dual could be either unbounded or infeasible.
340 TERMINATION_REASON_PRIMAL_INFEASIBLE = 2;
341 // Note in this situation the primal could be either unbounded or infeasible.
342 TERMINATION_REASON_DUAL_INFEASIBLE = 3;
343 TERMINATION_REASON_TIME_LIMIT = 4;
344 TERMINATION_REASON_ITERATION_LIMIT = 5;
345 TERMINATION_REASON_KKT_MATRIX_PASS_LIMIT = 8;
346 TERMINATION_REASON_INTERRUPTED_BY_USER = 12;
347 TERMINATION_REASON_NUMERICAL_ERROR = 6;
348 // Indicates that the solver detected invalid problem data, e.g., inconsistent
349 // bounds.
350 TERMINATION_REASON_INVALID_PROBLEM = 9;
351 // Indicates that the solver detected that the initial solution that was
352 // provided was invalid, e.g., wrong size or containing NAN or inf.
353 TERMINATION_REASON_INVALID_INITIAL_SOLUTION = 13;
354 // Indicates that an invalid value for the parameters was detected.
355 TERMINATION_REASON_INVALID_PARAMETER = 10;
356 TERMINATION_REASON_OTHER = 7;
357 // Primal or dual infeasibility was detected (e.g. by presolve) but no
358 // certificate is available.
359 TERMINATION_REASON_PRIMAL_OR_DUAL_INFEASIBLE = 11;
360}
361
362enum PolishingPhaseType {
363 POLISHING_PHASE_TYPE_UNSPECIFIED = 0;
364 POLISHING_PHASE_TYPE_PRIMAL_FEASIBILITY = 1;
365 POLISHING_PHASE_TYPE_DUAL_FEASIBILITY = 2;
366}
367
368// Details about one primal feasibility or dual feasibility polishing phase
369// within a solve with `use_feasibility_polishing`. See `SolveLog` for
370// descriptions of the fields with the same name.
371message FeasibilityPolishingDetails {
372 optional PolishingPhaseType polishing_phase_type = 1;
373 // The iteration count for the main iteration when this feasibility polishing
374 // phase was triggered.
375 optional int32 main_iteration_count = 2;
376 optional PrimalDualHybridGradientParams params = 3;
377 optional TerminationReason termination_reason = 4;
378 optional int32 iteration_count = 5;
379 optional double solve_time_sec = 6;
380 optional IterationStats solution_stats = 7;
381 optional PointType solution_type = 8;
382 repeated IterationStats iteration_stats = 9;
383}
384
385message SolveLog {
386 // The name of the optimization problem.
387 optional string instance_name = 1;
388
389 // If solved with PDLP, the parameters for this solve.
390 optional PrimalDualHybridGradientParams params = 14;
391
392 // The reason that the solve terminated.
393 optional TerminationReason termination_reason = 3;
394
395 // Optional extra information about the termination reason.
396 optional string termination_string = 4;
397
398 // The total number of iterations during the solve. For a solve with
399 // `use_feasibility_polishing` this count includes the iterations from
400 // the feasibility polishing phases.
401 optional int32 iteration_count = 5;
402
403 // Time for preprocessing (everything before iteration 0). This is also
404 // included in `solve_time_sec`.
405 optional double preprocessing_time_sec = 13;
406
407 // The runtime of the solve. Note: This should not be used for comparing
408 // methods unless care is taken to control for noise in runtime measurement.
409 // For a solve with `use_feasibility_polishing` this count includes the
410 // iterations from the feasibility polishing phases.
411 optional double solve_time_sec = 6;
412
413 // The `IterationStats` for the final iteration of the solver. For a solve
414 // with `use_feasibility_polishing`, the work metrics (iteration_count,
415 // cumulative_kkt_matrix_passes, etc.) will include the work done in the
416 // feasibility polishing phases.
417 // NOTE: Regardless of preprocessing (i.e. scaling or presolve) the optimality
418 // or infeasibility information is evaluated with respect to the original
419 // problem.
420 optional IterationStats solution_stats = 8;
421
422 // The type of the output point that the solver returned. The quality of the
423 // point is reported in the corresponding entry of
424 // solution_stats.convergence_information and/or
425 // solution_stats.infeasibility_information. If termination_reason is
426 // TERMINATION_REASON_OPTIMAL, it's guaranteed that the corresponding entry of
427 // solution_stats.convergence_information satisfies the optimality conditions.
428 // Similarly, if termination_reason is either
429 // TERMINATION_REASON_PRIMAL_INFEASIBLE or TERMINATION_REASON_DUAL_INFEASIBLE
430 // the corresponding entry of solution_stats.infeasibility_information
431 // satisifes conditions for declaring primal or dual infeasibility,
432 // respectively.
433 // If termination_reason is anything else, e.g. TERMINATION_REASON_TIME_LIMIT
434 // or TERMINATION_REASON_PRIMAL_OR_DUAL_INFEASIBLE, the solution may not
435 // satisfy the optimality or infeasibility conditions.
436 optional PointType solution_type = 10;
437
438 // A history of iteration stats for the solve. The iteration_number fields
439 // should be in increasing order. The frequency at which these stats should be
440 // recorded is not specified. This field is "more" optional than the others
441 // because it often significantly increases the size of the message, and
442 // because the information may not be available for third-party solvers.
443 // For a solve with `use_feasibility_polishing`, these iteration stats will
444 // only reflect the work done in the main iterations (not the feasibility
445 // polishing phases).
446 repeated IterationStats iteration_stats = 7;
447
448 // Statistics of the original problem.
449 optional QuadraticProgramStats original_problem_stats = 11;
450
451 // Statistics of the problem after preprocessing.
452 optional QuadraticProgramStats preprocessed_problem_stats = 12;
453
454 // If solving with `use_feasibility_polishing`, details about the primal and
455 // dual feasibility polishing phases.
456 repeated FeasibilityPolishingDetails feasibility_polishing_details = 15;
457
458 reserved 2, 9;
459}