54 static absl::StatusOr<std::unique_ptr<GurobiSolver>>
New(
55 const ModelProto& input_model,
58 absl::StatusOr<SolveResultProto>
Solve(
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();
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(
const SolveParametersProto&
parameters);
264 absl::Status AddNewLinearConstraints(
265 const LinearConstraintsProto& constraints);
266 absl::Status AddNewQuadraticConstraints(
267 const google::protobuf::Map<QuadraticConstraintId,
268 QuadraticConstraintProto>& constraints);
269 absl::Status AddNewSecondOrderConeConstraints(
270 const google::protobuf::Map<SecondOrderConeConstraintId,
271 SecondOrderConeConstraintProto>& constraints);
272 absl::Status AddNewSosConstraints(
273 const google::protobuf::Map<AnyConstraintId, SosConstraintProto>&
276 absl::flat_hash_map<int64_t, SosConstraintData>& constraints_map);
277 absl::Status AddNewIndicatorConstraints(
278 const google::protobuf::Map<IndicatorConstraintId,
279 IndicatorConstraintProto>& constraints);
280 absl::Status AddNewVariables(
const VariablesProto& new_variables);
281 absl::Status AddSingleObjective(
const ObjectiveProto& objective);
282 absl::Status AddMultiObjectives(
283 const ObjectiveProto& primary_objective,
284 const google::protobuf::Map<int64_t, ObjectiveProto>&
285 auxiliary_objectives);
291 absl::Status AddNewMultiObjective(
292 const ObjectiveProto& objective,
293 std::optional<AuxiliaryObjectiveId> objective_id,
bool is_maximize);
294 absl::Status AddNewSlacks(
295 const std::vector<LinearConstraintData*>& new_slacks);
296 absl::Status ChangeCoefficients(
const SparseDoubleMatrixProto& matrix);
298 absl::Status ResetQuadraticObjectiveTerms(
299 const SparseDoubleMatrixProto& terms);
302 absl::Status UpdateQuadraticObjectiveTerms(
303 const SparseDoubleMatrixProto& terms);
304 absl::Status LoadModel(
const ModelProto& input_model);
306 absl::Status UpdateDoubleListAttribute(
const SparseDoubleVectorProto& update,
307 const char* attribute_name,
309 absl::Status UpdateInt32ListAttribute(
const SparseInt32VectorProto& update,
310 const char* attribute_name,
313 struct DeletedIndices {
314 std::vector<GurobiVariableIndex> variables;
315 std::vector<GurobiLinearConstraintIndex> linear_constraints;
316 std::vector<GurobiQuadraticConstraintIndex> quadratic_constraints;
317 std::vector<GurobiSosConstraintIndex> sos_constraints;
318 std::vector<GurobiGeneralConstraintIndex> general_constraints;
321 void UpdateGurobiIndices(
const DeletedIndices& deleted_indices);
322 absl::Status UpdateLinearConstraints(
323 const LinearConstraintUpdatesProto& update,
324 std::vector<GurobiVariableIndex>& deleted_variables_index);
326 int get_model_index(GurobiVariableIndex
index)
const {
return index; }
327 int get_model_index(
const LinearConstraintData&
index)
const {
328 return index.constraint_index;
335 template <
typename T>
336 void GurobiVectorToSparseDoubleVector(
337 absl::Span<const double> gurobi_values,
const T& map,
338 SparseDoubleVectorProto& result,
339 const SparseVectorFilterProto& filter)
const;
340 absl::StatusOr<BasisProto> GetGurobiBasis();
341 absl::Status SetGurobiBasis(
const BasisProto& basis);
342 absl::StatusOr<DualRayProto> GetGurobiDualRay(
343 const SparseVectorFilterProto& linear_constraints_filter,
344 const SparseVectorFilterProto& variables_filter,
bool is_maximize);
346 absl::StatusOr<bool> IsMIP()
const;
348 absl::StatusOr<bool> IsQP()
const;
350 absl::StatusOr<bool> IsQCP()
const;
352 absl::StatusOr<std::unique_ptr<GurobiCallbackData>> RegisterCallback(
353 const CallbackRegistrationProto& registration,
Callback cb,
358 absl::StatusOr<InvertedBounds> ListInvertedBounds()
const;
362 bool is_multi_objective_mode()
const;
366 absl::StatusOr<InvalidIndicators> ListInvalidIndicators()
const;
368 struct VariableEqualToExpression {
369 GurobiVariableIndex variable_index;
370 GurobiLinearConstraintIndex constraint_index;
375 std::optional<VariableId> TryExtractVariable(
376 const LinearExpressionProto& expression);
384 absl::StatusOr<VariableEqualToExpression>
385 CreateSlackVariableEqualToExpression(
const LinearExpressionProto& expression);
387 absl::Status SetMultiObjectiveTolerances(
388 const ModelSolveParametersProto& model_parameters);
390 absl::Status ResetModelParameters(
391 const ModelSolveParametersProto& model_parameters);
393 const std::unique_ptr<Gurobi> gurobi_;
406 absl::flat_hash_map<std::optional<AuxiliaryObjectiveId>,
407 GurobiMultiObjectiveIndex>
408 multi_objectives_map_;
412 linear_constraints_map_;
415 absl::flat_hash_map<QuadraticConstraintId, GurobiQuadraticConstraintIndex>
416 quadratic_constraints_map_;
419 absl::flat_hash_map<SecondOrderConeConstraintId,
420 SecondOrderConeConstraintData>
421 soc_constraints_map_;
424 absl::flat_hash_map<Sos1ConstraintId, SosConstraintData>
425 sos1_constraints_map_;
428 absl::flat_hash_map<Sos2ConstraintId, SosConstraintData>
429 sos2_constraints_map_;
434 absl::flat_hash_map<IndicatorConstraintId,
435 std::optional<IndicatorConstraintData>>
436 indicator_constraints_map_;
443 int num_gurobi_variables_ = 0;
445 int num_gurobi_lin_cons_ = 0;
447 int num_gurobi_quad_cons_ = 0;
449 int num_gurobi_sos_cons_ = 0;
451 int num_gurobi_gen_cons_ = 0;
458 absl::flat_hash_map<std::pair<VariableId, VariableId>,
double>
459 quadratic_objective_coefficients_;
465 absl::flat_hash_set<VariableId> undeletable_variables_;
467 static constexpr int kGrbBasicConstraint = 0;
468 static constexpr int kGrbNonBasicConstraint = -1;