Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
model_summary.cc
Go to the documentation of this file.
1// Copyright 2010-2025 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
15
16#include <cstdint>
17#include <initializer_list>
18#include <limits>
19#include <optional>
20#include <string>
21#include <utility>
22
23#include "absl/container/flat_hash_map.h"
24#include "absl/log/check.h"
25#include "absl/status/status.h"
26#include "absl/status/statusor.h"
27#include "absl/strings/string_view.h"
28#include "absl/types/span.h"
34
35namespace operations_research {
36namespace math_opt {
37
38namespace internal {
39
41 absl::Span<const int64_t> ids) {
42 int64_t previous{-1};
43 for (int i = 0; i < ids.size(); previous = ids[i], ++i) {
44 if (ids[i] < 0 || ids[i] == std::numeric_limits<int64_t>::max()) {
46 << "Expected ids to be nonnegative and not max(int64_t) but at "
47 "index "
48 << i << " found id: " << ids[i];
49 }
50 if (ids[i] <= previous) {
52 << "Expected ids to be strictly increasing, but at index " << i
53 << " found id: " << ids[i] << " and at previous index " << i - 1
54 << " found id: " << ids[i - 1];
55 }
56 }
57 return absl::OkStatus();
58}
59
60} // namespace internal
61
63 std::initializer_list<std::pair<int64_t, absl::string_view>> ids)
64 : IdNameBiMap(/*check_names=*/true) {
65 for (const auto& pair : ids) {
66 CHECK_OK(Insert(pair.first, std::string(pair.second)));
67 }
68}
69
70IdNameBiMap::IdNameBiMap(const IdNameBiMap& other) { *this = other; }
71
73 if (&other == this) {
74 return *this;
75 }
76 next_free_id_ = other.next_free_id_;
77 id_to_name_ = other.id_to_name_;
78 if (!other.nonempty_name_to_id_.has_value()) {
79 nonempty_name_to_id_ = std::nullopt;
80 } else {
81 nonempty_name_to_id_.emplace();
82 for (const auto& [id, name] : id_to_name_) {
83 if (!name.empty()) {
84 const auto [it, success] =
85 nonempty_name_to_id_->insert({absl::string_view(name), id});
86 CHECK(success); // CHECK is OK, other cannot have duplicate names and
87 // non nullopt nonempty_name_to_id_.
88 }
89 }
90 }
91
92 return *this;
93}
94
96 absl::Span<const int64_t> deleted_ids, absl::Span<const int64_t> new_ids,
97 const absl::Span<const std::string* const> names) {
99 << "invalid deleted ids";
101 << "invalid new ids";
102 if (!names.empty() && names.size() != new_ids.size()) {
104 << "names had size " << names.size()
105 << " but should either be empty of have size matching new_ids which "
106 "has size "
107 << new_ids.size();
108 }
109 for (const int64_t id : deleted_ids) {
111 }
112 for (int i = 0; i < new_ids.size(); ++i) {
114 Insert(new_ids[i], names.empty() ? std::string{} : *names[i]));
115 }
116 return absl::OkStatus();
117}
118
119ModelSummary::ModelSummary(const bool check_names)
120 : variables(check_names),
121 auxiliary_objectives(check_names),
122 linear_constraints(check_names),
123 quadratic_constraints(check_names),
125 sos1_constraints(check_names),
126 sos2_constraints(check_names),
127 indicator_constraints(check_names) {}
128
129absl::StatusOr<ModelSummary> ModelSummary::Create(const ModelProto& model,
130 const bool check_names) {
131 ModelSummary summary(check_names);
132 summary.maximize = model.objective().maximize();
133 RETURN_IF_ERROR(summary.variables.BulkUpdate({}, model.variables().ids(),
134 model.variables().names()))
135 << "ModelProto.variables are invalid";
137 {}, model.auxiliary_objectives(), summary.auxiliary_objectives))
138 << "ModelProto.auxiliary_objectives are invalid";
139 {
140 absl::string_view objective_name = model.objective().name();
141 if (summary.auxiliary_objectives.HasName(objective_name)) {
143 << "duplicate objective name: " << objective_name;
144 }
145 summary.primary_objective_name = objective_name;
146 }
148 {}, model.linear_constraints().ids(), model.linear_constraints().names()))
149 << "ModelProto.linear_constraints are invalid";
151 {}, model.quadratic_constraints(), summary.quadratic_constraints))
152 << "ModelProto.quadratic_constraints are invalid";
156 << "ModelProto.second_order_cone_constraints are invalid";
158 {}, model.sos1_constraints(), summary.sos1_constraints))
159 << "ModelProto.sos1_constraints are invalid";
161 {}, model.sos2_constraints(), summary.sos2_constraints))
162 << "ModelProto.sos2_constraints are invalid";
164 {}, model.indicator_constraints(), summary.indicator_constraints))
165 << "ModelProto.indicator_constraints are invalid";
166 return summary;
167}
168
169absl::Status ModelSummary::Update(const ModelUpdateProto& model_update) {
170 if (model_update.objective_updates().has_direction_update()) {
172 }
173 RETURN_IF_ERROR(variables.BulkUpdate(model_update.deleted_variable_ids(),
174 model_update.new_variables().ids(),
175 model_update.new_variables().names()))
176 << "invalid variables";
181 << "invalid auxiliary objectives";
184 << "duplicate objective name: " << primary_objective_name;
185 }
187 model_update.deleted_linear_constraint_ids(),
188 model_update.new_linear_constraints().ids(),
189 model_update.new_linear_constraints().names()))
190 << "invalid linear constraints";
195 << "invalid quadratic constraints";
201 << "invalid second-order cone constraints";
206 << "invalid sos1 constraints";
211 << "invalid sos2 constraints";
216 << "invalid indicator constraints";
217 return absl::OkStatus();
218}
219
220} // namespace math_opt
221} // namespace operations_research
#define RETURN_IF_ERROR(expr)
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveProto > & new_objectives() const
absl::Status Erase(int64_t id)
Removes the given id, or returns an error if id is not present.
bool HasName(absl::string_view name) const
Will always return false if name is empty or if check_names was false.
IdNameBiMap & operator=(const IdNameBiMap &other)
absl::Status BulkUpdate(absl::Span< const int64_t > deleted_ids, absl::Span< const int64_t > new_ids, absl::Span< const std::string *const > names)
absl::Status Insert(int64_t id, std::string name)
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::IndicatorConstraintProto > & new_constraints() const
const ::std::string & names(int index) const
Definition model.pb.h:3316
const ::operations_research::math_opt::VariablesProto & variables() const
Definition model.pb.h:4404
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::QuadraticConstraintProto > & quadratic_constraints() const
Definition model.pb.h:4819
const ::operations_research::math_opt::LinearConstraintsProto & linear_constraints() const
Definition model.pb.h:4629
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SosConstraintProto > & sos1_constraints() const
Definition model.pb.h:4877
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SosConstraintProto > & sos2_constraints() const
Definition model.pb.h:4906
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SecondOrderConeConstraintProto > & second_order_cone_constraints() const
Definition model.pb.h:4848
const ::operations_research::math_opt::ObjectiveProto & objective() const
Definition model.pb.h:4502
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveProto > & auxiliary_objectives() const
Definition model.pb.h:4599
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::IndicatorConstraintProto > & indicator_constraints() const
Definition model.pb.h:4935
const ::operations_research::math_opt::SosConstraintUpdatesProto & sos1_constraint_updates() const
::int64_t deleted_linear_constraint_ids(int index) const
const ::operations_research::math_opt::LinearConstraintsProto & new_linear_constraints() const
const ::operations_research::math_opt::AuxiliaryObjectivesUpdatesProto & auxiliary_objectives_updates() const
const ::operations_research::math_opt::QuadraticConstraintUpdatesProto & quadratic_constraint_updates() const
const ::operations_research::math_opt::SosConstraintUpdatesProto & sos2_constraint_updates() const
const ::operations_research::math_opt::IndicatorConstraintUpdatesProto & indicator_constraint_updates() const
const ::operations_research::math_opt::ObjectiveUpdatesProto & objective_updates() const
const ::operations_research::math_opt::SecondOrderConeConstraintUpdatesProto & second_order_cone_constraint_updates() const
const ::operations_research::math_opt::VariablesProto & new_variables() const
const ::std::string & name() const
Definition model.pb.h:3072
bool has_direction_update() const
optional bool direction_update = 1;
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::QuadraticConstraintProto > & new_constraints() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SecondOrderConeConstraintProto > & new_constraints() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SosConstraintProto > & new_constraints() const
const ::std::string & names(int index) const
Definition model.pb.h:2781
absl::Status UpdateBiMapFromMappedData(const absl::Span< const int64_t > deleted_ids, const google::protobuf::Map< int64_t, DataProto > &proto_map, IdNameBiMap &bimap)
absl::Status CheckIdsRangeAndStrictlyIncreasing2(absl::Span< const int64_t > ids)
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
In SWIG mode, we don't want anything besides these top-level includes.
StatusBuilder InvalidArgumentErrorBuilder()
absl::Status Update(const ModelUpdateProto &model_update)
static absl::StatusOr< ModelSummary > Create(const ModelProto &model, bool check_names=true)