54 static absl::StatusOr<std::unique_ptr<GurobiSolver>>
New(
55 const ModelProto& input_model,
58 absl::StatusOr<SolveResultProto>
Solve(
59 const SolveParametersProto& parameters,
60 const ModelSolveParametersProto& model_parameters,
62 const CallbackRegistrationProto& callback_registration,
Callback cb,
64 absl::StatusOr<bool>
Update(
const ModelUpdateProto& model_update)
override;
65 absl::StatusOr<ComputeInfeasibleSubsystemResultProto>
71 struct GurobiCallbackData {
74 : callback_input(std::move(callback_input)),
75 local_interrupter(local_interrupter) {}
90 absl::Status status = absl::OkStatus();
93 explicit GurobiSolver(std::unique_ptr<Gurobi> g_gurobi);
96 using VariableId = int64_t;
97 using AuxiliaryObjectiveId = int64_t;
98 using LinearConstraintId = int64_t;
99 using QuadraticConstraintId = int64_t;
100 using SecondOrderConeConstraintId = int64_t;
101 using Sos1ConstraintId = int64_t;
102 using Sos2ConstraintId = int64_t;
103 using IndicatorConstraintId = int64_t;
104 using AnyConstraintId = int64_t;
105 using GurobiVariableIndex = int;
106 using GurobiMultiObjectiveIndex = int;
107 using GurobiLinearConstraintIndex = int;
108 using GurobiQuadraticConstraintIndex = int;
109 using GurobiSosConstraintIndex = int;
113 using GurobiGeneralConstraintIndex = int;
114 using GurobiAnyConstraintIndex = int;
116 static constexpr GurobiVariableIndex kUnspecifiedIndex = -1;
117 static constexpr GurobiAnyConstraintIndex kUnspecifiedConstraint = -2;
118 static constexpr double kInf = std::numeric_limits<double>::infinity();
120 struct GurobiModelElements {
121 std::vector<GurobiVariableIndex> variables;
122 std::vector<GurobiLinearConstraintIndex> linear_constraints;
123 std::vector<GurobiQuadraticConstraintIndex> quadratic_constraints;
124 std::vector<GurobiSosConstraintIndex> sos_constraints;
125 std::vector<GurobiGeneralConstraintIndex> general_constraints;
134 struct LinearConstraintData {
137 GurobiModelElements DependentElements()
const;
139 GurobiLinearConstraintIndex constraint_index = kUnspecifiedConstraint;
141 GurobiVariableIndex slack_index = kUnspecifiedIndex;
142 double lower_bound = -kInf;
143 double upper_bound = kInf;
146 struct SecondOrderConeConstraintData {
149 GurobiModelElements DependentElements()
const;
151 GurobiQuadraticConstraintIndex constraint_index = kUnspecifiedConstraint;
152 std::vector<GurobiVariableIndex> slack_variables;
153 std::vector<GurobiLinearConstraintIndex> slack_constraints;
156 struct SosConstraintData {
159 GurobiModelElements DependentElements()
const;
161 GurobiSosConstraintIndex constraint_index = kUnspecifiedConstraint;
162 std::vector<GurobiVariableIndex> slack_variables;
163 std::vector<GurobiLinearConstraintIndex> slack_constraints;
166 struct IndicatorConstraintData {
169 GurobiGeneralConstraintIndex constraint_index;
172 int64_t indicator_variable_id;
175 struct SolutionClaims {
176 bool primal_feasible_solution_exists;
177 bool dual_feasible_solution_exists;
180 struct SolutionsAndClaims {
181 std::vector<SolutionProto> solutions;
182 SolutionClaims solution_claims;
185 template <
typename SolutionType>
186 struct SolutionAndClaim {
187 std::optional<SolutionType>
solution;
188 bool feasible_solution_exists =
false;
193 absl::StatusOr<SolveResultProto> ExtractSolveResultProto(
194 absl::Time start,
const ModelSolveParametersProto& model_parameters);
195 absl::Status FillRays(
const ModelSolveParametersProto& model_parameters,
196 SolutionClaims solution_claims,
197 SolveResultProto& result);
198 absl::StatusOr<GurobiSolver::SolutionsAndClaims> GetSolutions(
199 const ModelSolveParametersProto& model_parameters);
200 absl::StatusOr<SolveStatsProto> GetSolveStats(absl::Time start)
const;
202 absl::StatusOr<double> GetGurobiBestDualBound()
const;
203 absl::StatusOr<double> GetBestDualBound(
204 absl::Span<const SolutionProto> solutions)
const;
205 absl::StatusOr<double> GetBestPrimalBound(
206 absl::Span<const SolutionProto> solutions)
const;
208 bool PrimalSolutionQualityAvailable()
const;
209 absl::StatusOr<double> GetPrimalSolutionQuality()
const;
212 absl::StatusOr<bool> AnyElementInIIS(
const GurobiModelElements& grb_elements);
214 absl::StatusOr<std::optional<ModelSubsetProto::Bounds>> VariableBoundsInIIS(
215 GurobiVariableIndex grb_index);
217 absl::StatusOr<bool> VariableInIIS(GurobiVariableIndex grb_index);
218 absl::StatusOr<std::optional<ModelSubsetProto::Bounds>> LinearConstraintInIIS(
219 const LinearConstraintData& grb_data);
220 absl::StatusOr<std::optional<ModelSubsetProto::Bounds>>
221 QuadraticConstraintInIIS(GurobiQuadraticConstraintIndex grb_index);
226 absl::StatusOr<ComputeInfeasibleSubsystemResultProto>
227 ExtractComputeInfeasibleSubsystemResultProto(
bool proven_infeasible);
230 absl::StatusOr<bool> IsMaximize()
const;
232 absl::StatusOr<TerminationProto> ConvertTerminationReason(
233 int gurobi_status, SolutionClaims solution_claims,
234 double best_primal_bound,
double best_dual_bound);
238 absl::StatusOr<SolutionsAndClaims> GetLpSolution(
239 const ModelSolveParametersProto& model_parameters);
242 absl::StatusOr<SolutionsAndClaims> GetQpSolution(
243 const ModelSolveParametersProto& model_parameters);
246 absl::StatusOr<SolutionsAndClaims> GetQcpSolution(
247 const ModelSolveParametersProto& model_parameters);
251 absl::StatusOr<SolutionsAndClaims> GetMipSolutions(
252 const ModelSolveParametersProto& model_parameters);
255 absl::StatusOr<SolutionAndClaim<PrimalSolutionProto>>
256 GetConvexPrimalSolutionIfAvailable(
257 const ModelSolveParametersProto& model_parameters);
258 absl::StatusOr<SolutionAndClaim<DualSolutionProto>>
259 GetConvexDualSolutionIfAvailable(
260 const ModelSolveParametersProto& model_parameters);
261 absl::StatusOr<std::optional<BasisProto>> GetBasisIfAvailable();
263 absl::Status SetParameters(
264 const SolveParametersProto& parameters,
265 const ModelSolveParametersProto& model_parameters = {});
266 absl::Status AddNewLinearConstraints(
267 const LinearConstraintsProto& constraints);
268 absl::Status AddNewQuadraticConstraints(
269 const google::protobuf::Map<QuadraticConstraintId,
270 QuadraticConstraintProto>& constraints);
271 absl::Status AddNewSecondOrderConeConstraints(
272 const google::protobuf::Map<SecondOrderConeConstraintId,
273 SecondOrderConeConstraintProto>& constraints);
274 absl::Status AddNewSosConstraints(
275 const google::protobuf::Map<AnyConstraintId, SosConstraintProto>&
278 absl::flat_hash_map<int64_t, SosConstraintData>& constraints_map);
279 absl::Status AddNewIndicatorConstraints(
280 const google::protobuf::Map<IndicatorConstraintId,
281 IndicatorConstraintProto>& constraints);
282 absl::Status AddNewVariables(
const VariablesProto& new_variables);
283 absl::Status AddSingleObjective(
const ObjectiveProto& objective);
284 absl::Status AddMultiObjectives(
285 const ObjectiveProto& primary_objective,
286 const google::protobuf::Map<int64_t, ObjectiveProto>&
287 auxiliary_objectives);
293 absl::Status AddNewMultiObjective(
294 const ObjectiveProto& objective,
295 std::optional<AuxiliaryObjectiveId> objective_id,
bool is_maximize);
296 absl::Status AddNewSlacks(
297 const std::vector<LinearConstraintData*>& new_slacks);
298 absl::Status ChangeCoefficients(
const SparseDoubleMatrixProto& matrix);
300 absl::Status ResetQuadraticObjectiveTerms(
301 const SparseDoubleMatrixProto& terms);
304 absl::Status UpdateQuadraticObjectiveTerms(
305 const SparseDoubleMatrixProto& terms);
306 absl::Status LoadModel(
const ModelProto& input_model);
308 absl::Status UpdateDoubleListAttribute(
const SparseDoubleVectorProto& update,
309 const char* attribute_name,
310 const IdHashMap& id_hash_map);
311 absl::Status UpdateInt32ListAttribute(
const SparseInt32VectorProto& update,
312 const char* attribute_name,
313 const IdHashMap& id_hash_map);
315 struct DeletedIndices {
316 std::vector<GurobiVariableIndex> variables;
317 std::vector<GurobiLinearConstraintIndex> linear_constraints;
318 std::vector<GurobiQuadraticConstraintIndex> quadratic_constraints;
319 std::vector<GurobiSosConstraintIndex> sos_constraints;
320 std::vector<GurobiGeneralConstraintIndex> general_constraints;
323 void UpdateGurobiIndices(
const DeletedIndices& deleted_indices);
324 absl::Status UpdateLinearConstraints(
325 const LinearConstraintUpdatesProto& update,
326 std::vector<GurobiVariableIndex>& deleted_variables_index);
328 int get_model_index(GurobiVariableIndex index)
const {
return index; }
329 int get_model_index(
const LinearConstraintData& index)
const {
330 return index.constraint_index;
337 template <
typename T>
338 void GurobiVectorToSparseDoubleVector(
339 absl::Span<const double> gurobi_values,
const T& map,
340 SparseDoubleVectorProto& result,
341 const SparseVectorFilterProto& filter)
const;
342 absl::StatusOr<BasisProto> GetGurobiBasis();
343 absl::Status SetGurobiBasis(
const BasisProto& basis);
344 absl::StatusOr<DualRayProto> GetGurobiDualRay(
345 const SparseVectorFilterProto& linear_constraints_filter,
346 const SparseVectorFilterProto& variables_filter,
bool is_maximize);
348 absl::StatusOr<bool> IsMIP()
const;
350 absl::StatusOr<bool> IsQP()
const;
352 absl::StatusOr<bool> IsQCP()
const;
354 absl::StatusOr<std::unique_ptr<GurobiCallbackData>> RegisterCallback(
355 const CallbackRegistrationProto& registration,
Callback cb,
360 absl::StatusOr<InvertedBounds> ListInvertedBounds()
const;
364 bool is_multi_objective_mode()
const;
368 absl::StatusOr<InvalidIndicators> ListInvalidIndicators()
const;
370 struct VariableEqualToExpression {
371 GurobiVariableIndex variable_index;
372 GurobiLinearConstraintIndex constraint_index;
377 std::optional<VariableId> TryExtractVariable(
378 const LinearExpressionProto& expression);
386 absl::StatusOr<VariableEqualToExpression>
387 CreateSlackVariableEqualToExpression(
const LinearExpressionProto& expression);
390 absl::Status SetMultiObjectiveParameters(
391 const ModelSolveParametersProto& model_parameters);
393 absl::Status ResetModelParameters(
394 const ModelSolveParametersProto& model_parameters);
396 const std::unique_ptr<Gurobi> gurobi_;
409 absl::flat_hash_map<std::optional<AuxiliaryObjectiveId>,
410 GurobiMultiObjectiveIndex>
411 multi_objectives_map_;
415 linear_constraints_map_;
418 absl::flat_hash_map<QuadraticConstraintId, GurobiQuadraticConstraintIndex>
419 quadratic_constraints_map_;
422 absl::flat_hash_map<SecondOrderConeConstraintId,
423 SecondOrderConeConstraintData>
424 soc_constraints_map_;
427 absl::flat_hash_map<Sos1ConstraintId, SosConstraintData>
428 sos1_constraints_map_;
431 absl::flat_hash_map<Sos2ConstraintId, SosConstraintData>
432 sos2_constraints_map_;
437 absl::flat_hash_map<IndicatorConstraintId,
438 std::optional<IndicatorConstraintData>>
439 indicator_constraints_map_;
446 int num_gurobi_variables_ = 0;
448 int num_gurobi_lin_cons_ = 0;
450 int num_gurobi_quad_cons_ = 0;
452 int num_gurobi_sos_cons_ = 0;
454 int num_gurobi_gen_cons_ = 0;
461 absl::flat_hash_map<std::pair<VariableId, VariableId>,
double>
462 quadratic_objective_coefficients_;
468 absl::flat_hash_set<VariableId> undeletable_variables_;
470 static constexpr int kGrbBasicConstraint = 0;
471 static constexpr int kGrbNonBasicConstraint = -1;