21 #include "absl/container/flat_hash_set.h"
22 #include "absl/status/status.h"
23 #include "absl/strings/string_view.h"
24 #include "absl/log/check.h"
27 #include "ortools/math_opt/callback.pb.h"
29 #include "ortools/math_opt/model.pb.h"
30 #include "ortools/math_opt/model_update.pb.h"
31 #include "ortools/math_opt/result.pb.h"
32 #include "ortools/math_opt/sparse_containers.pb.h"
38 CHECK_EQ(sparse_vector.ids_size(), sparse_vector.values_size());
45 if (!(
value == 0.0)) {
46 sparse_vector.set_ids(
next,
id);
53 sparse_vector.mutable_ids()->Truncate(
next);
54 sparse_vector.mutable_values()->Truncate(
next);
58 const SparseVectorFilterProto& filter)
65 const auto& ids = filter_.filtered_ids();
66 CHECK(std::adjacent_find(ids.begin(), ids.end(),
67 std::greater_equal<int64_t>()) == ids.end())
68 <<
"The input filter.filtered_ids must be strictly increasing.";
72 absl::flat_hash_set<CallbackEventProto>
EventSet(
73 const CallbackRegistrationProto& callback_registration) {
77 absl::flat_hash_set<CallbackEventProto> events;
78 for (
int i = 0; i < callback_registration.request_registration_size(); ++i) {
79 events.emplace(callback_registration.request_registration(i));
85 const absl::string_view detail) {
86 TerminationProto result;
88 result.set_reason(TERMINATION_REASON_FEASIBLE);
90 result.set_reason(TERMINATION_REASON_NO_SOLUTION_FOUND);
92 result.set_limit(limit);
93 if (!detail.empty()) {
94 result.set_detail(std::string(detail));
100 const absl::string_view detail) {
105 const absl::string_view detail) {
110 const absl::string_view detail) {
111 TerminationProto result;
112 result.set_reason(reason);
113 if (!detail.empty()) {
114 result.set_detail(std::string(detail));
121 const absl::string_view solver_name) {
122 const auto error_status = [solver_name](
123 const absl::string_view structure,
128 << solver_name <<
" does not support " << structure;
131 <<
"MathOpt does not currently support " << solver_name
132 <<
" models with " << structure;
134 LOG(FATAL) <<
"Unexpected call with `kSupported`";
139 for (
const bool is_integer :
model.variables().integers()) {
141 return error_status(
"integer variables", support);
147 if (!
model.auxiliary_objectives().empty()) {
148 return error_status(
"multi objectives", support);
153 if (!
model.objective().quadratic_coefficients().row_ids().empty()) {
154 return error_status(
"quadratic objectives", support);
156 for (
const auto& [_, objective] :
model.auxiliary_objectives()) {
157 if (!objective.quadratic_coefficients().row_ids().empty()) {
158 return error_status(
"quadratic objectives", support);
164 if (!
model.quadratic_constraints().empty()) {
165 return error_status(
"quadratic constraints", support);
170 if (!
model.sos1_constraints().empty()) {
171 return error_status(
"sos1 constraints", support);
176 if (!
model.sos2_constraints().empty()) {
177 return error_status(
"sos2 constraints", support);
182 if (!
model.indicator_constraints().empty()) {
183 return error_status(
"indicator constraints", support);
186 return absl::OkStatus();
192 for (
const bool is_integer :
193 update.variable_updates().integers().values()) {
198 for (
const bool is_integer : update.new_variables().integers()) {
205 if (!update.auxiliary_objectives_updates()
206 .deleted_objective_ids()
208 !update.auxiliary_objectives_updates().new_objectives().empty() ||
209 !update.auxiliary_objectives_updates().objective_updates().empty()) {
214 if (!update.objective_updates()
215 .quadratic_coefficients()
220 for (
const auto& [_, new_objective] :
221 update.auxiliary_objectives_updates().new_objectives()) {
222 if (!new_objective.quadratic_coefficients().row_ids().empty()) {
226 for (
const auto& [_, objective_update] :
227 update.auxiliary_objectives_updates().objective_updates()) {
228 if (!objective_update.quadratic_coefficients().row_ids().empty()) {
235 const auto contains_new_or_deleted_constraints =
236 [](
const auto& constraint_update) {
237 return !constraint_update.new_constraints().empty() ||
238 !constraint_update.deleted_constraint_ids().empty();
241 if (contains_new_or_deleted_constraints(
242 update.quadratic_constraint_updates())) {
247 if (contains_new_or_deleted_constraints(update.sos1_constraint_updates())) {
252 if (contains_new_or_deleted_constraints(update.sos2_constraint_updates())) {
257 if (contains_new_or_deleted_constraints(
258 update.indicator_constraint_updates())) {
SparseVectorFilterPredicate(const SparseVectorFilterProto &filter)
TerminationProto FeasibleTermination(const LimitProto limit, const absl::string_view detail)
absl::Status ModelIsSupported(const ModelProto &model, const SupportedProblemStructures &support_menu, const absl::string_view solver_name)
bool UpdateIsSupported(const ModelUpdateProto &update, const SupportedProblemStructures &support_menu)
TerminationProto TerminateForLimit(const LimitProto limit, const bool feasible, const absl::string_view detail)
TerminationProto NoSolutionFoundTermination(const LimitProto limit, const absl::string_view detail)
TerminationProto TerminateForReason(const TerminationReasonProto reason, const absl::string_view detail)
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
absl::flat_hash_set< CallbackEventProto > EventSet(const CallbackRegistrationProto &callback_registration)
void RemoveSparseDoubleVectorZeros(SparseDoubleVectorProto &sparse_vector)
Collection of objects used to extend the Constraint Solver library.
StatusBuilder UnimplementedErrorBuilder()
StatusBuilder InvalidArgumentErrorBuilder()
SupportType integer_variables
SupportType quadratic_constraints
SupportType sos1_constraints
SupportType indicator_constraints
SupportType multi_objectives
SupportType sos2_constraints
SupportType quadratic_objectives