OR-Tools  9.2
callback.h
Go to the documentation of this file.
1// Copyright 2010-2021 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// Data types for using callbacks with MathOpt.
15//
16// Callbacks allow to user to observe the progress of a solver and modify its
17// behavior mid solve. This is supported by allowing the user to a function of
18// type MathOpt::Callback as an optional argument to MathOpt::Solve(). This
19// function is called periodically throughout the solve process. This file
20// defines the data types needed to use this callback.
21//
22// The example below registers a callback that listens for feasible solutions
23// the solvers finds along the way and accumulates them in a list for analysis
24// after the solve.
25//
26// using ::operations_research::math_opt::CallbackData;
27// using ::operations_research::math_opt::CallbackRegistration;
28// using ::operations_research::math_opt::CallbackResult;
29// using ::operations_research::math_opt::MathOpt;
30// using ::operations_research::math_opt::Result;
31// using ::operations_research::math_opt::Variable;
32// using ::operations_research::math_opt::VariableMap;
33//
34// MathOpt model(operations_research::math_opt::SOLVER_TYPE_GUROBI);
35// Variable x = model.AddBinaryVariable();
36// model.objective().Maximize(x);
37// CallbackRegistration cb_reg;
38// cb_reg.events = {
39// operations_research::math_opt::CALLBACK_EVENT_MIP_SOLUTION};
40// std::vector<VariableMap<double>> solutions;
41// auto cb = [&solutions](const CallbackData& cb_data) {
42// // NOTE: this assumes the callback is always called from the same thread.
43// // Gurobi always does this, multi-threaded SCIP does not.
44// solutions.push_back(*cb_data.solution);
45// return CallbackResult();
46// };
47// absl::StatusOr<Result> result = opt.Solve({}, {}, cb_reb, cb);
48//
49// At the termination of the example, solutions will have {{x, 1.0}}, and
50// possibly {{x, 0.0}} as well.
51//
52// If the callback argument to MathOpt::Solve() is not null, it will be invoked
53// on the events specified by the callback_registration argument (and when the
54// callback is null, callback_registration must not request any events or will
55// CHECK fail). Some solvers do not support callbacks or certain events, in this
56// case the callback is ignored. TODO(b/180617976): change this behavior.
57//
58// Some solvers may call callback from multiple threads (SCIP will, Gurobi
59// will not). You should either solve with one thread (see
60// solver_parameters.common_parameters.threads), write a threadsafe callback,
61// or consult the documentation of your underlying solver.
62#ifndef OR_TOOLS_MATH_OPT_CPP_CALLBACK_H_
63#define OR_TOOLS_MATH_OPT_CPP_CALLBACK_H_
64
65#include <string>
66#include <utility>
67#include <vector>
68
69#include "absl/container/flat_hash_set.h"
70#include "absl/time/time.h"
71#include "absl/types/optional.h"
72#include "ortools/math_opt/callback.pb.h"
76
77namespace operations_research {
78namespace math_opt {
79
80// The input to the MathOpt::Callback function.
81//
82// The information available depends on the current event.
84 // Users will typically not need this function.
85 // Will CHECK fail if proto is not valid.
86 CallbackData(IndexedModel* model, const CallbackDataProto& proto);
87 CallbackData() = default;
88
89 // The current state of the underlying solver.
90 CallbackEventProto event = CALLBACK_EVENT_UNSPECIFIED;
91
92 // If event == CALLBACK_EVENT_MIP_NODE, the primal_solution contains the
93 // primal solution to the current LP-node relaxation. In some cases, no
94 // solution will be available (e.g. because LP was infeasible or the solve
95 // was imprecise).
96 // If event == CALLBACK_EVENT_MIP_SOLUTION, the primal_solution contains the
97 // newly found primal (integer) feasible solution. The solution is always
98 // present.
99 // Otherwise, the primal_solution is not available.
100 absl::optional<VariableMap<double>> solution;
101
102 // If event == CALLBACK_EVENT_MESSAGE, contains the messages from the solver.
103 // Each message represents a single output line from the solver, and each
104 // message does not contain any '\n' characters.
105 // Otherwise, messages is empty.
106 std::vector<std::string> messages;
107
108 // Time since `Solve()` was called. Available for all events except
109 // CALLBACK_EVENT_POLLING.
110 absl::Duration runtime;
111
112 // Only available for event == CALLBACK_EVENT_PRESOLVE.
113 CallbackDataProto::PresolveStats presolve_stats;
114
115 // Only available for event == CALLBACK_EVENT_SIMPLEX.
116 CallbackDataProto::SimplexStats simplex_stats;
117
118 // Only available for event == CALLBACK_EVENT_BARRIER.
119 CallbackDataProto::BarrierStats barrier_stats;
120
121 // Only available for event of CALLBACK_EVENT_MIP, CALLBACK_EVENT_MIP_NODE, or
122 // CALLBACK_EVENT_MIP_SOLUTION.
123 CallbackDataProto::MipStats mip_stats;
124};
125
126// Provided with a callback at the start of a Solve() to inform the solver:
127// * what information the callback needs,
128// * how the callback might alter the solve process.
130 // Will CHECK fail if referenced variables are not from the same model.
131 CallbackRegistrationProto Proto() const;
132
133 // Returns the model referenced variables, or null if no variables are
134 // referenced. Will CHECK fail if variables are not from the same model.
135 IndexedModel* model() const;
136
137 // The events the solver should invoke the callback at.
138 absl::flat_hash_set<CallbackEventProto> events;
139
140 // Restricts the variable returned in CallbackData.solution for event
141 // CALLBACK_EVENT_MIP_SOLUTION. This can improve performance.
143
144 // Restricts the variable returned in CallbackData.solution for event
145 // CALLBACK_EVENT_MIP_NODE. This can improve performance.
147
148 // If the callback will ever add "user cuts" at event CALLBACK_EVENT_MIP_NODE
149 // during the solve process (a linear constraint that excludes the current LP
150 // solution but does not cut off any integer points).
151 bool add_cuts = false;
152
153 // If the callback will ever add "lazy constraints" at event
154 // CALLBACK_EVENT_MIP_NODE or CALLBACK_EVENT_MIP_SOLUTION during the solve
155 // process (a linear constraint that excludes integer points).
157};
158
159// The value returned by the MathOpt::Callback function.
161 // Prefer AddUserCut and AddLazyConstraint below instead of using this
162 // directly.
165 bool is_lazy = false;
166
168 };
169
170 // Adds a "user cut," a linear constraint that excludes the current LP
171 // solution but does not cut off any integer points. Use only for
172 // CALLBACK_EVENT_MIP_NODE.
173 void AddUserCut(BoundedLinearExpression linear_constraint) {
174 new_constraints.push_back({std::move(linear_constraint), false});
175 }
176
177 // Adds a "lazy constraint," a linear constraint that excludes integer points.
178 // Use only for CALLBACK_EVENT_MIP_NODE and CALLBACK_EVENT_MIP_SOLUTION.
180 new_constraints.push_back({std::move(linear_constraint), true});
181 }
182
183 // Will CHECK fail if referenced variables are not from the same model.
184 CallbackResultProto Proto() const;
185
186 // Returns the model referenced variables, or null if no variables are
187 // referenced. Will CHECK fail if variables are not from the same model.
188 //
189 // Runs in O(num constraints + num suggested solutions).
190 IndexedModel* model() const;
191
192 // Stop the solve process and return early. Can be called from any event.
193 bool terminate = false;
194
195 // The user cuts and lazy constraints added. Prefer AddUserCut() and
196 // AddLazyConstraint() to modifying this directly.
197 std::vector<GeneratedLinearConstraint> new_constraints;
198
199 // A solution or partially defined solution to give to the solver.
200 std::vector<VariableMap<double>> suggested_solutions;
201};
202
203} // namespace math_opt
204} // namespace operations_research
205
206#endif // OR_TOOLS_MATH_OPT_CPP_CALLBACK_H_
CpModelProto proto
GRBmodel * model
Collection of objects used to extend the Constraint Solver library.
std::vector< std::string > messages
Definition: callback.h:106
CallbackDataProto::PresolveStats presolve_stats
Definition: callback.h:113
absl::optional< VariableMap< double > > solution
Definition: callback.h:100
CallbackDataProto::SimplexStats simplex_stats
Definition: callback.h:116
CallbackDataProto::BarrierStats barrier_stats
Definition: callback.h:119
CallbackDataProto::MipStats mip_stats
Definition: callback.h:123
CallbackRegistrationProto Proto() const
Definition: callback.cc:98
absl::flat_hash_set< CallbackEventProto > events
Definition: callback.h:138
std::vector< VariableMap< double > > suggested_solutions
Definition: callback.h:200
void AddLazyConstraint(BoundedLinearExpression linear_constraint)
Definition: callback.h:179
CallbackResultProto Proto() const
Definition: callback.cc:120
void AddUserCut(BoundedLinearExpression linear_constraint)
Definition: callback.h:173
std::vector< GeneratedLinearConstraint > new_constraints
Definition: callback.h:197