Google OR-Tools v9.9
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
gscip_solver.h
Go to the documentation of this file.
1// Copyright 2010-2024 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_SOLVERS_GSCIP_SOLVER_H_
15#define OR_TOOLS_MATH_OPT_SOLVERS_GSCIP_SOLVER_H_
16
17#include <cstdint>
18#include <memory>
19#include <optional>
20#include <utility>
21#include <vector>
22
23#include "absl/container/flat_hash_map.h"
24#include "absl/container/flat_hash_set.h"
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
27#include "absl/types/span.h"
29#include "ortools/gscip/gscip.h"
30#include "ortools/gscip/gscip.pb.h"
32#include "ortools/math_opt/callback.pb.h"
37#include "ortools/math_opt/infeasible_subsystem.pb.h"
38#include "ortools/math_opt/model.pb.h"
39#include "ortools/math_opt/model_parameters.pb.h"
40#include "ortools/math_opt/model_update.pb.h"
41#include "ortools/math_opt/parameters.pb.h"
42#include "ortools/math_opt/result.pb.h"
44#include "ortools/math_opt/sparse_containers.pb.h"
45#include "scip/type_cons.h"
46#include "scip/type_var.h"
47
48namespace operations_research {
49namespace math_opt {
50
52 public:
53 static absl::StatusOr<std::unique_ptr<SolverInterface>> New(
54 const ModelProto& model, const InitArgs& init_args);
55
56 absl::StatusOr<SolveResultProto> Solve(
57 const SolveParametersProto& parameters,
58 const ModelSolveParametersProto& model_parameters,
59 MessageCallback message_cb,
60 const CallbackRegistrationProto& callback_registration, Callback cb,
61 SolveInterrupter* interrupter) override;
62 absl::StatusOr<bool> Update(const ModelUpdateProto& model_update) override;
63 absl::StatusOr<ComputeInfeasibleSubsystemResultProto>
64 ComputeInfeasibleSubsystem(const SolveParametersProto& parameters,
65 MessageCallback message_cb,
66 SolveInterrupter* interrupter) override;
67
68 // Returns the merged parameters and a list of warnings for unsupported
69 // parameters.
70 static absl::StatusOr<GScipParameters> MergeParameters(
71 const SolveParametersProto& solve_parameters);
72
73 private:
74 // A simple class for managing extra variables and constraints introduced to
75 // model higher-level constructs.
76 //
77 // This is useful when auxiliary variables and constraints are introduced
78 // transparently to the user, and must be deleted when the corresponding
79 // higher-level construct is deleted.
80 struct AuxiliaryStructureHandler {
81 // Removes all registered slack variables and constraints from the model.
82 // Those deleted variables and constraints are then dropped from this
83 // handler (i.e., this function is idempotent).
84 absl::Status DeleteStructure(GScip& gscip);
85
86 std::vector<SCIP_VAR*> variables;
87 std::vector<SCIP_CONS*> constraints;
88 };
89
90 explicit GScipSolver(std::unique_ptr<GScip> gscip);
91
92 // Adds the new variables.
93 absl::Status AddVariables(const VariablesProto& variables,
94 const absl::flat_hash_map<int64_t, double>&
95 linear_objective_coefficients);
96
97 // Update existing variables' parameters. Returns false if the update cannot
98 // be performed (namely, if attempting to update bounds on a binary variable).
99 absl::StatusOr<bool> UpdateVariables(
100 const VariableUpdatesProto& variable_updates);
101
102 absl::Status AddQuadraticObjectiveTerms(
103 const SparseDoubleMatrixProto& new_qp_terms, bool maximize);
104
105 // Adds the new linear constraints.
106 absl::Status AddLinearConstraints(
107 const LinearConstraintsProto& linear_constraints,
108 const SparseDoubleMatrixProto& linear_constraint_matrix);
109
110 // Updates the existing constraints and the coefficients of the existing
111 // variables of these constraints.
112 absl::Status UpdateLinearConstraints(
113 LinearConstraintUpdatesProto linear_constraint_updates,
114 const SparseDoubleMatrixProto& linear_constraint_matrix,
115 std::optional<int64_t> first_new_var_id,
116 std::optional<int64_t> first_new_cstr_id);
117
118 absl::Status AddQuadraticConstraints(
119 const google::protobuf::Map<int64_t, QuadraticConstraintProto>&
120 quadratic_constraints);
121
122 absl::Status AddIndicatorConstraints(
123 const google::protobuf::Map<int64_t, IndicatorConstraintProto>&
124 indicator_constraints);
125
126 // Given a linear `expression`, add a new `variable` and constraint such that
127 // `variable == expression`. Returns the associated SCIP pointers to the new
128 // slack variable and constraint.
129 absl::StatusOr<std::pair<SCIP_VAR*, SCIP_CONS*>>
130 AddSlackVariableEqualToExpression(const LinearExpressionProto& expression);
131
132 // Unpacks a `SosConstraintProto` into the associated data for GScip. As the
133 // MathOpt protos allow SOS terms to be arbitrary linear expressions, slack
134 // variables and constraints to represent nontrivial expressions are added to
135 // the model and tracked by the returned `AuxiliaryStructureHandler`.
136 absl::StatusOr<std::pair<GScipSOSData, AuxiliaryStructureHandler>>
137 ProcessSosProto(const SosConstraintProto& sos_constraint);
138
139 absl::Status AddSos1Constraints(
140 const google::protobuf::Map<int64_t, SosConstraintProto>&
141 sos1_constraints);
142 absl::Status AddSos2Constraints(
143 const google::protobuf::Map<int64_t, SosConstraintProto>&
144 sos2_constraints);
145
146 absl::flat_hash_set<SCIP_VAR*> LookupAllVariables(
147 absl::Span<const int64_t> variable_ids);
148 absl::StatusOr<SolveResultProto> CreateSolveResultProto(
149 GScipResult gscip_result,
150 const ModelSolveParametersProto& model_parameters,
151 std::optional<double> cutoff);
152
153 // Returns the ids of variables and linear constraints with inverted bounds.
154 InvertedBounds ListInvertedBounds() const;
155
156 // Returns the indicator constraints with non-binary indicator variables.
157 InvalidIndicators ListInvalidIndicators() const;
158
159 // Warning: it is critical that GScipConstraintHandlerData outlive its
160 // associated SCIP_CONS*. When GScip fails, we want this to be cleaned up
161 // after gscip_. See documentation on
162 // GScipConstraintHandler::AddCallbackConstraint().
163 std::unique_ptr<GScipSolverConstraintData> constraint_data_;
164 const std::unique_ptr<GScip> gscip_;
165 GScipSolverConstraintHandler constraint_handler_;
166
168 bool has_quadratic_objective_ = false;
169 absl::flat_hash_map<int64_t, SCIP_CONS*> linear_constraints_;
170 absl::flat_hash_map<int64_t, SCIP_CONS*> quadratic_constraints_;
171 // Values, if unset, correspond to indicator constraints with unset indicator
172 // variables. If set, tracks the constraint pointer and indicator variable ID.
173 // The constraint pointer must be non-null.
174 absl::flat_hash_map<int64_t, std::optional<std::pair<SCIP_CONS*, int64_t>>>
175 indicator_constraints_;
176 absl::flat_hash_map<int64_t, std::pair<SCIP_CONS*, AuxiliaryStructureHandler>>
177 sos1_constraints_;
178 absl::flat_hash_map<int64_t, std::pair<SCIP_CONS*, AuxiliaryStructureHandler>>
179 sos2_constraints_;
180};
181
182} // namespace math_opt
183} // namespace operations_research
184
185#endif // OR_TOOLS_MATH_OPT_SOLVERS_GSCIP_SOLVER_H_
absl::StatusOr< ComputeInfeasibleSubsystemResultProto > ComputeInfeasibleSubsystem(const SolveParametersProto &parameters, MessageCallback message_cb, SolveInterrupter *interrupter) override
absl::StatusOr< bool > Update(const ModelUpdateProto &model_update) override
static absl::StatusOr< GScipParameters > MergeParameters(const SolveParametersProto &solve_parameters)
absl::StatusOr< SolveResultProto > Solve(const SolveParametersProto &parameters, const ModelSolveParametersProto &model_parameters, MessageCallback message_cb, const CallbackRegistrationProto &callback_registration, Callback cb, SolveInterrupter *interrupter) override
static absl::StatusOr< std::unique_ptr< SolverInterface > > New(const ModelProto &model, const InitArgs &init_args)
std::function< void(const std::vector< std::string > &)> MessageCallback
std::function< absl::StatusOr< CallbackResultProto >( const CallbackDataProto &)> Callback
SatParameters parameters
absl::Span< const int64_t > variable_ids
GRBmodel * model
In SWIG mode, we don't want anything besides these top-level includes.