OR-Tools  9.6
solver.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 #ifndef OR_TOOLS_MATH_OPT_CORE_SOLVER_H_
15 #define OR_TOOLS_MATH_OPT_CORE_SOLVER_H_
16 
17 #include <functional>
18 #include <memory>
19 
20 #include "absl/status/status.h"
21 #include "absl/status/statusor.h"
22 #include "absl/synchronization/mutex.h"
23 #include "ortools/math_opt/callback.pb.h"
28 #include "ortools/math_opt/model.pb.h"
29 #include "ortools/math_opt/model_parameters.pb.h"
30 #include "ortools/math_opt/model_update.pb.h"
31 #include "ortools/math_opt/parameters.pb.h"
32 #include "ortools/math_opt/result.pb.h"
33 
34 namespace operations_research {
35 namespace math_opt {
36 
37 // A solver for a given model and solver implementation.
38 //
39 // Use the New() function to build a new solver instance; then call Solve() to
40 // solve the model. You can then update the model using Update() and resolve.
41 //
42 // Thread-safety: methods Solve() and Update() must not be called concurrently;
43 // they will immediately return with an error status if this happens. Some
44 // solvers may add more restriction regarding threading. Please see
45 // SOLVER_TYPE_XXX documentation for details.
46 //
47 // Usage:
48 // const ModelProto model = ...;
49 // const auto solver = Solver::New(SOLVER_TYPE_GSCIP,
50 // model,
51 // /*arguments=*/{});
52 // CHECK_OK(solver.status());
53 // Solver::SolveArgs solve_arguments;
54 // ...
55 //
56 // // First solve of the initial Model.
57 // const auto first_solution = (*solver)->Solve(solve_arguments);
58 // CHECK_OK(first_solution.status());
59 // // Use the first_solution here.
60 //
61 // // Update the Model with a ModelUpdate.
62 // const ModelUpdate update = ...;
63 // CHECK_OK((*solver)->Update(update));
64 // const auto second_solution = (*solver)->Solve(solve_arguments);
65 // CHECK_OK(second_solution.status());
66 // // Use the second_solution of the updated problem here.
67 //
68 class Solver {
69  public:
71 
72  // Callback function for messages callback sent by the solver.
73  //
74  // Each message represents a single output line from the solver, and each
75  // message does not contain any '\n' character in it.
76  //
77  // Thread-safety: a callback may be called concurrently from multiple
78  // threads. The users is expected to use proper synchronization primitives to
79  // deal with that.
81 
82  // Callback function type for MIP/LP callbacks.
83  using Callback = std::function<CallbackResultProto(const CallbackDataProto&)>;
84 
85  // Arguments used when calling Solve() to solve the problem.
86  struct SolveArgs {
87  SolveParametersProto parameters;
88  ModelSolveParametersProto model_parameters;
89 
90  // An optional callback for messages emitted by the solver.
91  //
92  // When set it enables the solver messages and ignores the `enable_output`
93  // in solve parameters; messages are redirected to the callback and not
94  // printed on stdout/stderr/logs anymore.
96 
97  CallbackRegistrationProto callback_registration;
98  Callback user_cb = nullptr;
99 
100  // An optional interrupter that the solver can use to interrupt the solve
101  // early.
103  };
104 
105  // A shortcut for calling Solver::New() and then Solver::Solve().
106  static absl::StatusOr<SolveResultProto> NonIncrementalSolve(
107  const ModelProto& model, SolverTypeProto solver_type,
108  const InitArgs& init_args, const SolveArgs& solve_args);
109 
110  // Builds a solver of the given type with the provided model and
111  // initialization parameters.
112  static absl::StatusOr<std::unique_ptr<Solver>> New(
113  SolverTypeProto solver_type, const ModelProto& model,
114  const InitArgs& arguments);
115 
116  Solver(const Solver&) = delete;
117  Solver& operator=(const Solver&) = delete;
118 
119  ~Solver();
120 
121  // Solves the current model (included all updates).
122  absl::StatusOr<SolveResultProto> Solve(const SolveArgs& arguments);
123 
124  // Updates the model to solve and returns true, or returns false if this
125  // update is not supported by the underlying solver.
126  //
127  // A status error will be returned if the model_update is invalid or the
128  // underlying solver has an internal error.
129  //
130  // When this function returns false, the Solver object is in a failed
131  // state. In that case the underlying SolverInterface implementation has been
132  // destroyed (this enables the caller to instantiate a new Solver without
133  // destroying the previous one first even if they use Gurobi with a single-use
134  // license).
135  absl::StatusOr<bool> Update(const ModelUpdateProto& model_update);
136 
137  private:
138  Solver(std::unique_ptr<SolverInterface> underlying_solver,
139  ModelSummary model_summary);
140 
141  // Tracker used to ensure that Solve() and Update() are not called
142  // concurrently.
143  ConcurrentCallsGuard::Tracker concurrent_calls_tracker_;
144 
145  // Can be nullptr only if fatal_failure_occurred_ is true (but the contrary is
146  // not true). This happens when Update() returns false.
147  std::unique_ptr<SolverInterface> underlying_solver_;
148 
149  ModelSummary model_summary_;
150 
151  // Set to true if a previous call to Solve() or Update() returned a failing
152  // status (or if Update() returned false).
153  //
154  // This is guarded by concurrent_calls_tracker_.
155  bool fatal_failure_occurred_ = false;
156 };
157 
158 namespace internal {
159 
160 // Validates that the input streamable and non_streamable init arguments are
161 // either not set or are the one of solver_type.
162 absl::Status ValidateInitArgs(const Solver::InitArgs& init_args,
163  SolverTypeProto solver_type);
164 
165 } // namespace internal
166 } // namespace math_opt
167 } // namespace operations_research
168 
169 #endif // OR_TOOLS_MATH_OPT_CORE_SOLVER_H_
static absl::StatusOr< SolveResultProto > NonIncrementalSolve(const ModelProto &model, SolverTypeProto solver_type, const InitArgs &init_args, const SolveArgs &solve_args)
Definition: solver.cc:75
absl::StatusOr< SolveResultProto > Solve(const SolveArgs &arguments)
Definition: solver.cc:106
SolverInterface::MessageCallback MessageCallback
Definition: solver.h:80
std::function< CallbackResultProto(const CallbackDataProto &)> Callback
Definition: solver.h:83
static absl::StatusOr< std::unique_ptr< Solver > > New(SolverTypeProto solver_type, const ModelProto &model, const InitArgs &arguments)
Definition: solver.cc:93
Solver & operator=(const Solver &)=delete
absl::StatusOr< bool > Update(const ModelUpdateProto &model_update)
Definition: solver.cc:161
std::function< void(const std::vector< std::string > &)> MessageCallback
GRBmodel * model
absl::Status ValidateInitArgs(const Solver::InitArgs &init_args, const SolverTypeProto solver_type)
Definition: solver.cc:192
Collection of objects used to extend the Constraint Solver library.
CallbackRegistrationProto callback_registration
Definition: solver.h:97
ModelSolveParametersProto model_parameters
Definition: solver.h:88