Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
callback.proto
Go to the documentation of this file.
1// Copyright 2010-2025 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// Solver-Callback handling protos:
15// Callback functions allow for a fine-grain control, and ongoing interaction
16// with the solver during the solve process. The overall architecture is that
17// upon solve invocation the user will select what type of interactions to have
18// with the solver, and whenever the solver offers an interaction enabled by the
19// user, return the statistics collected up to that point, and any additional
20// information required by the user. Once done, the callback function must
21// return a message to the solver to continue with the solve process.
22syntax = "proto3";
23
24package operations_research.math_opt;
25
26import "google/protobuf/duration.proto";
27import "ortools/math_opt/sparse_containers.proto";
28
29option java_package = "com.google.ortools.mathopt";
30option java_multiple_files = true;
31
32// The supported events during a solve for callbacks.
33enum CallbackEventProto {
34 CALLBACK_EVENT_UNSPECIFIED = 0;
35
36 // The solver is currently running presolve.
37 //
38 // This event is supported by SOLVER_TYPE_GUROBI only.
39 CALLBACK_EVENT_PRESOLVE = 1;
40
41 // The solver is currently running the simplex method.
42 //
43 // This event is supported by SOLVER_TYPE_GUROBI only.
44 CALLBACK_EVENT_SIMPLEX = 2;
45
46 // The solver is in the MIP loop (called periodically before starting a new
47 // node). Useful for early termination. Note that this event does not provide
48 // information on LP relaxations nor about new incumbent solutions.
49 //
50 // This event is fully supported for MIP models by SOLVER_TYPE_GUROBI only. If
51 // used with SOLVER_TYPE_CP_SAT, it is called when the dual bound is improved.
52 CALLBACK_EVENT_MIP = 3;
53
54 // Called every time a new MIP incumbent is found.
55 //
56 // This event is fully supported for MIP models by SOLVER_TYPE_GUROBI.
57 // SOLVER_TYPE_CP_SAT has partial support: you can view the solutions and
58 // request termination, but you cannot add lazy constraints. Other solvers
59 // don't support this event.
60 CALLBACK_EVENT_MIP_SOLUTION = 4;
61
62 // Called inside a MIP node. Note that there is no guarantee that the
63 // callback function will be called on every node. That behavior is
64 // solver-dependent.
65 //
66 // Disabling cuts using SolveParametersProto may interfere with this event
67 // being called and/or adding cuts at this event, the behavior is solver
68 // specific.
69 //
70 // This event is supported for MIP models by SOLVER_TYPE_GUROBI only.
71 CALLBACK_EVENT_MIP_NODE = 5;
72
73 // Called in each iterate of an interior point/barrier method.
74 //
75 // This event is supported for SOLVER_TYPE_GUROBI only.
76 CALLBACK_EVENT_BARRIER = 6;
77}
78
79// The callback function input data.
80// Note that depending on the event, some information might be unavailable.
81message CallbackDataProto {
82 CallbackEventProto event = 1;
83 // if event == CALLBACK_EVENT_MIP_NODE, the primal_solution_vector contains
84 // the variable values of the primal solution for the current LP-node
85 // relaxation. In some cases, no solution will be available (e.g. because
86 // LP was infeasible or the solve was imprecise).
87 // if event == CALLBACK_EVENT_MIP_SOLUTION, the primal_solution_vector
88 // contains variable values for the newly found primal (integer) feasible
89 // solution.
90 // Otherwise, the primal_solution_vector is not available.
91 //
92 // Note that, because of variable filters, it is possible that when a solution
93 // is found, it is empty. The message will be set but left empty in this case,
94 // while it will be unset when no solution is available.
95 SparseDoubleVectorProto primal_solution_vector = 2;
96
97 // Running time since the `Solve` call.
98 google.protobuf.Duration runtime = 3;
99
100 // Presolve stats. Only available during CALLBACK_EVENT_PRESOLVE.
101 message PresolveStats {
102 optional int64 removed_variables = 1;
103 optional int64 removed_constraints = 2;
104 optional int64 bound_changes = 3;
105 optional int64 coefficient_changes = 4;
106 }
107 PresolveStats presolve_stats = 4;
108
109 // Simplex stats. Only available during CALLBACK_EVENT_SIMPLEX.
110 message SimplexStats {
111 optional int64 iteration_count = 1;
112 optional double objective_value = 2;
113 optional double primal_infeasibility = 3;
114 optional double dual_infeasibility = 4;
115 optional bool is_pertubated = 5;
116 }
117 SimplexStats simplex_stats = 5;
118
119 // Barrier stats. Only available during CALLBACK_EVENT_BARRIER.
120 message BarrierStats {
121 optional int32 iteration_count = 1;
122 optional double primal_objective = 2;
123 optional double dual_objective = 3;
124 optional double complementarity = 4;
125 optional double primal_infeasibility = 5;
126 optional double dual_infeasibility = 6;
127 }
128 BarrierStats barrier_stats = 6;
129
130 // MIP B&B stats. Only available during CALLBACK_EVENT_MIPxxxx events.
131 // When using CP-SAT, only primal_bound, dual_bound and
132 // number_of_solutions_found are populated.
133 message MipStats {
134 optional double primal_bound = 1;
135 optional double dual_bound = 2;
136 optional int64 explored_nodes = 3;
137 optional int64 open_nodes = 4;
138 optional int64 simplex_iterations = 5;
139 optional int32 number_of_solutions_found = 6;
140 optional int32 cutting_planes_in_lp = 7;
141 }
142 MipStats mip_stats = 7;
143}
144
145// Return value of a callback function.
146message CallbackResultProto {
147 message GeneratedLinearConstraint {
148 // This message encode linear constraints of the form
149 // lower_bound <= linear_expression <= upper_bound
150 SparseDoubleVectorProto linear_expression = 1;
151 double lower_bound = 2;
152 double upper_bound = 3;
153
154 // Two types of generated linear constraints are supported based on is_lazy:
155 // * The "lazy constraint" can remove integer points from the feasible
156 // region and can be added at event CALLBACK_EVENT_MIP_NODE or
157 // CALLBACK_EVENT_MIP_SOLUTION
158 // * The "user cut" (on is_lazy=false) strengthens the LP without removing
159 // integer points. It can only be added at CALLBACK_EVENT_MIP_NODE.
160 bool is_lazy = 4;
161 }
162
163 // When true it tells the solver to interrupt the solve as soon as possible.
164 //
165 // It can be set from any event. This is equivalent to using a
166 // SolveInterrupter and triggering it from the callback.
167 //
168 // Some solvers don't support interruption, in that case this is simply
169 // ignored and the solve terminates as usual. On top of that solvers may not
170 // immediately stop the solve. Thus the user should expect the callback to
171 // still be called after they set `terminate` to true in a previous
172 // call. Returning with `terminate` false after having previously returned
173 // true won't cancel the interruption.
174 bool terminate = 1;
175
176 // TODO(b/172214608): SCIP allows to reject a feasible solution without
177 // providing a cut. This is something we might support at a later stage.
178
179 // Dynamically generated linear constraints to add to the MIP. See
180 // GeneratedLinearConstraint::is_lazy for details.
181 repeated GeneratedLinearConstraint cuts = 4;
182
183 // Use only for CALLBACK_EVENT_MIP_NODE.
184 //
185 // Note that some solvers (e.g. Gurobi) support partially-defined solutions.
186 // The most common use case is to specify a value for each variable in the
187 // model. If a variable is not present in the primal solution, its value is
188 // taken to be undefined, and is up to the underlying solver to deal with it.
189 // For example, Gurobi will try to solve a Sub-MIP to get a fully feasible
190 // solution if necessary.
191 repeated SparseDoubleVectorProto suggested_solutions = 5;
192}
193
194// Provided with a callback at the start of a Solve() to inform the solver:
195// * what information the callback needs,
196// * how the callback might alter the solve process.
197message CallbackRegistrationProto {
198 // The events the solver should invoke the callback at.
199 //
200 // When a solver is called with registered events that are not supported,
201 // an InvalidArgument is returned. The supported events may depend on the
202 // model. For example registering for CALLBACK_EVENT_MIP with a model that
203 // only contains continuous variables will fail for most solvers. See the
204 // documentation of each event to see their supported solvers/model types.
205 repeated CallbackEventProto request_registration = 1;
206
207 // If CALLBACK_EVENT_MIP_SOLUTION is in `request_registration`, then
208 // the returned primal_solution information will be filtered according to
209 // this rule.
210 SparseVectorFilterProto mip_solution_filter = 2;
211
212 // If CALLBCK_EVENT_MIP_NODE is in `request_registration`, then the
213 // returned primal_solution information will be filtered according to this
214 // rule.
215 SparseVectorFilterProto mip_node_filter = 3;
216
217 //////////////////////////////////////////////////////////////////////////////
218 // What might you do in your callback (typically some solver features need
219 // to be disabled before the solve starts to support these features).
220 //////////////////////////////////////////////////////////////////////////////
221
222 // Dynamically add linear constraints that strength the formulation but do not
223 // exclude integer points during CALLBACK_EVENT_MIP_NODE events.
224 bool add_cuts = 4;
225 // Dynamically add linear constraints that exclude integer points during
226 // CALLBACK_EVENT_MIP_NODE and/or CALLBACK_EVENT_MIP_SOLUTION events.
227 bool add_lazy_constraints = 5;
228}