14#ifndef OR_TOOLS_MATH_OPT_SOLVERS_GUROBI_SOLVER_H_
15#define OR_TOOLS_MATH_OPT_SOLVERS_GUROBI_SOLVER_H_
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
27#include "absl/strings/string_view.h"
28#include "absl/time/time.h"
29#include "absl/types/span.h"
33#include "ortools/math_opt/callback.pb.h"
37#include "ortools/math_opt/model.pb.h"
38#include "ortools/math_opt/model_parameters.pb.h"
39#include "ortools/math_opt/model_update.pb.h"
40#include "ortools/math_opt/parameters.pb.h"
41#include "ortools/math_opt/result.pb.h"
42#include "ortools/math_opt/solution.pb.h"
46#include "ortools/math_opt/sparse_containers.pb.h"
53 static absl::StatusOr<std::unique_ptr<GurobiSolver>>
New(
54 const ModelProto& input_model,
57 absl::StatusOr<SolveResultProto>
Solve(
59 const ModelSolveParametersProto& model_parameters,
61 const CallbackRegistrationProto& callback_registration,
Callback cb,
63 absl::Status
Update(
const ModelUpdateProto& model_update)
override;
64 bool CanUpdate(
const ModelUpdateProto& model_update)
override;
67 struct GurobiCallbackData {
70 : callback_input(std::move(callback_input)),
71 local_interrupter(local_interrupter) {}
86 absl::Status
status = absl::OkStatus();
92 using VariableId = int64_t;
93 using LinearConstraintId = int64_t;
94 using GurobiVariableIndex = int;
95 using GurobiLinearConstraintIndex = int;
97 static constexpr GurobiVariableIndex kUnspecifiedIndex = -1;
98 static constexpr GurobiLinearConstraintIndex kUnspecifiedConstraint = -2;
99 static constexpr double kInf = std::numeric_limits<double>::infinity();
106 struct ConstraintData {
107 GurobiLinearConstraintIndex constraint_index = kUnspecifiedConstraint;
109 GurobiVariableIndex slack_index = kUnspecifiedIndex;
115 LinearConstraintId id;
116 ConstraintData& constraint_data;
117 SlackInfo(
const LinearConstraintId input_id,
118 ConstraintData& input_constraint)
119 : id(input_id), constraint_data(input_constraint) {}
122 struct SolutionClaims {
123 bool primal_feasible_solution_exists;
124 bool dual_feasible_solution_exists;
127 struct SolutionsAndClaims {
128 std::vector<SolutionProto> solutions;
129 SolutionClaims solution_claims;
132 template <
typename SolutionType>
133 struct SolutionAndClaim {
134 std::optional<SolutionType> solution;
135 bool feasible_solution_exists =
false;
140 absl::StatusOr<ProblemStatusProto> GetProblemStatus(
141 const int grb_termination,
const SolutionClaims solution_claims);
142 absl::StatusOr<SolveResultProto> ExtractSolveResultProto(
143 absl::Time
start,
const ModelSolveParametersProto& model_parameters);
144 absl::Status FillRays(
const ModelSolveParametersProto& model_parameters,
145 SolveResultProto& result);
146 absl::StatusOr<GurobiSolver::SolutionsAndClaims> GetSolutions(
147 const ModelSolveParametersProto& model_parameters);
148 absl::StatusOr<SolveStatsProto> GetSolveStats(absl::Time
start,
149 SolutionClaims solution_claims);
151 absl::StatusOr<double> GetBestDualBound();
152 absl::StatusOr<double> GetBestPrimalBound(
bool has_primal_feasible_solution);
153 bool PrimalSolutionQualityAvailable()
const;
154 absl::StatusOr<double> GetPrimalSolutionQuality()
const;
157 absl::StatusOr<bool> IsMaximize()
const;
159 static absl::StatusOr<TerminationProto> ConvertTerminationReason(
160 int gurobi_status, SolutionClaims solution_claims);
162 absl::StatusOr<SolutionsAndClaims> GetQpSolution(
163 const ModelSolveParametersProto& model_parameters);
164 absl::StatusOr<SolutionsAndClaims> GetLpSolution(
165 const ModelSolveParametersProto& model_parameters);
166 absl::StatusOr<SolutionsAndClaims> GetMipSolutions(
167 const ModelSolveParametersProto& model_parameters);
170 absl::StatusOr<SolutionAndClaim<PrimalSolutionProto>>
171 GetConvexPrimalSolutionIfAvailable(
172 const ModelSolveParametersProto& model_parameters);
173 absl::StatusOr<SolutionAndClaim<DualSolutionProto>>
174 GetLpDualSolutionIfAvailable(
175 const ModelSolveParametersProto& model_parameters);
176 absl::StatusOr<std::optional<BasisProto>> GetBasisIfAvailable();
178 absl::Status SetParameters(
const SolveParametersProto&
parameters);
179 absl::Status AddNewConstraints(
const LinearConstraintsProto& constraints);
180 absl::Status AddNewVariables(
const VariablesProto& new_variables);
181 absl::Status AddNewSlacks(
const std::vector<SlackInfo>& new_slacks);
182 absl::Status ChangeCoefficients(
const SparseDoubleMatrixProto& matrix);
184 absl::Status ResetQuadraticObjectiveTerms(
185 const SparseDoubleMatrixProto& terms);
188 absl::Status UpdateQuadraticObjectiveTerms(
189 const SparseDoubleMatrixProto& terms);
190 absl::Status LoadModel(
const ModelProto& input_model);
192 absl::Status UpdateDoubleListAttribute(
const SparseDoubleVectorProto& update,
193 const char* attribute_name,
195 absl::Status UpdateInt32ListAttribute(
const SparseInt32VectorProto& update,
196 const char* attribute_name,
198 absl::Status UpdateGurobiIndices();
199 absl::Status UpdateLinearConstraints(
200 const LinearConstraintUpdatesProto& update,
201 std::vector<GurobiVariableIndex>& deleted_variables_index);
203 int num_gurobi_constraints()
const;
204 int get_model_index(GurobiVariableIndex
index)
const {
return index; }
205 int get_model_index(
const ConstraintData&
index)
const {
206 return index.constraint_index;
213 template <
typename T>
214 void GurobiVectorToSparseDoubleVector(
215 absl::Span<const double> gurobi_values,
const T& map,
216 SparseDoubleVectorProto& result,
217 const SparseVectorFilterProto& filter)
const;
218 absl::StatusOr<BasisProto> GetGurobiBasis();
219 absl::Status SetGurobiBasis(
const BasisProto& basis);
220 absl::StatusOr<DualRayProto> GetGurobiDualRay(
221 const SparseVectorFilterProto& linear_constraints_filter,
222 const SparseVectorFilterProto& variables_filter,
bool is_maximize);
223 absl::StatusOr<bool> IsLP()
const;
224 absl::StatusOr<bool> IsQP()
const;
226 absl::StatusOr<std::unique_ptr<GurobiCallbackData>> RegisterCallback(
227 const CallbackRegistrationProto& registration,
Callback cb,
232 absl::StatusOr<InvertedBounds> ListInvertedBounds()
const;
234 const std::unique_ptr<Gurobi> gurobi_;
245 linear_constraints_map_;
269 int num_gurobi_variables_ = 0;
275 absl::flat_hash_map<std::pair<VariableId, VariableId>,
double>
276 quadratic_objective_coefficients_;
278 static constexpr int kGrbBasicConstraint = 0;
279 static constexpr int kGrbNonBasicConstraint = -1;
bool CanUpdate(const ModelUpdateProto &model_update) override
absl::Status Update(const ModelUpdateProto &model_update) override
static absl::StatusOr< std::unique_ptr< GurobiSolver > > New(const ModelProto &input_model, const SolverInterface::InitArgs &init_args)
absl::StatusOr< SolveResultProto > Solve(const SolveParametersProto ¶meters, const ModelSolveParametersProto &model_parameters, MessageCallback message_cb, const CallbackRegistrationProto &callback_registration, Callback cb, SolveInterrupter *interrupter) override
std::function< void(const std::vector< std::string > &)> MessageCallback
std::function< absl::StatusOr< CallbackResultProto >(const CallbackDataProto &)> Callback
Collection of objects used to extend the Constraint Solver library.