Google OR-Tools v9.14
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
sparse_containers.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 <optional>
18#include <utility>
19#include <vector>
20
21#include "absl/algorithm/container.h"
22#include "absl/container/flat_hash_map.h"
23#include "absl/status/status.h"
24#include "absl/status/statusor.h"
25#include "absl/types/span.h"
26#include "google/protobuf/map.h"
38
40namespace {
41
42// SparseVectorProtoType should be SparseDoubleVector or SparseBasisStatusVector
43template <typename SparseVectorProtoType>
44absl::Status CheckSparseVectorProto(const SparseVectorProtoType& vec) {
47 return absl::OkStatus();
48}
49
50template <typename Key>
51absl::StatusOr<absl::flat_hash_map<Key, BasisStatus>> BasisVectorFromProto(
52 const ModelStorageCPtr model, const SparseBasisStatusVector& basis_proto) {
53 using IdType = typename Key::IdType;
54 absl::flat_hash_map<Key, BasisStatus> map;
55 map.reserve(basis_proto.ids_size());
56 for (const auto& [id, basis_status_proto_int] : MakeView(basis_proto)) {
57 const auto basis_status_proto =
58 static_cast<BasisStatusProto>(basis_status_proto_int);
59 const std::optional<BasisStatus> basis_status =
60 EnumFromProto(basis_status_proto);
61 if (!basis_status.has_value()) {
63 << "basis status not specified for id " << id;
64 }
65 map[Key(model, IdType(id))] = *basis_status;
66 }
67 return map;
68}
69
70template <typename Key>
72 const absl::flat_hash_map<Key, double>& id_map) {
73 using IdType = typename Key::IdType;
74 std::vector<std::pair<IdType, double>> sorted_entries;
75 sorted_entries.reserve(id_map.size());
76 for (const auto& [k, v] : id_map) {
77 sorted_entries.emplace_back(k.typed_id(), v);
78 }
79 absl::c_sort(sorted_entries);
81 for (const auto& [id, val] : sorted_entries) {
82 result.add_ids(id.value());
83 result.add_values(val);
84 }
85 return result;
86}
87
88template <typename Key>
89SparseBasisStatusVector BasisMapToProto(
90 const absl::flat_hash_map<Key, BasisStatus>& basis_map) {
91 using IdType = typename Key::IdType;
92 std::vector<std::pair<IdType, BasisStatus>> sorted_entries;
93 sorted_entries.reserve(basis_map.size());
94 for (const auto& [k, v] : basis_map) {
95 sorted_entries.emplace_back(k.typed_id(), v);
96 }
97 absl::c_sort(sorted_entries);
99 for (const auto& [id, val] : sorted_entries) {
100 result.add_ids(id.value());
101 result.add_values(EnumToProto(val));
102 }
103 return result;
104}
105
106absl::Status VariableIdsExist(const ModelStorageCPtr model,
107 const absl::Span<const int64_t> ids) {
108 for (const int64_t id : ids) {
109 if (!model->has_variable(VariableId(id))) {
111 << "no variable with id " << id << " exists";
112 }
113 }
114 return absl::OkStatus();
115}
116
117absl::Status LinearConstraintIdsExist(const ModelStorageCPtr model,
118 const absl::Span<const int64_t> ids) {
119 for (const int64_t id : ids) {
120 if (!model->has_linear_constraint(LinearConstraintId(id))) {
122 << "no linear constraint with id " << id << " exists";
123 }
124 }
125 return absl::OkStatus();
126}
127
128absl::Status QuadraticConstraintIdsExist(const ModelStorageCPtr model,
129 const absl::Span<const int64_t> ids) {
130 for (const int64_t id : ids) {
131 if (!model->has_constraint(QuadraticConstraintId(id))) {
133 << "no quadratic constraint with id " << id << " exists";
134 }
135 }
136 return absl::OkStatus();
137}
138
139} // namespace
140
141absl::StatusOr<VariableMap<double>> VariableValuesFromProto(
142 const ModelStorageCPtr model, const SparseDoubleVectorProto& vars_proto) {
143 RETURN_IF_ERROR(CheckSparseVectorProto(vars_proto));
144 RETURN_IF_ERROR(VariableIdsExist(model, vars_proto.ids()));
145 return MakeView(vars_proto).as_map<Variable>(model);
146}
147
148absl::StatusOr<VariableMap<int32_t>> VariableValuesFromProto(
149 const ModelStorageCPtr model, const SparseInt32VectorProto& vars_proto) {
150 RETURN_IF_ERROR(CheckSparseVectorProto(vars_proto));
151 RETURN_IF_ERROR(VariableIdsExist(model, vars_proto.ids()));
152 return MakeView(vars_proto).as_map<Variable>(model);
153}
154
156 const VariableMap<double>& variable_values) {
157 return MapToProto(variable_values);
158}
159
160absl::StatusOr<absl::flat_hash_map<Objective, double>>
162 const ModelStorageCPtr model,
163 const google::protobuf::Map<int64_t, double>& aux_obj_proto) {
164 absl::flat_hash_map<Objective, double> result;
165 for (const auto [raw_id, value] : aux_obj_proto) {
166 const AuxiliaryObjectiveId id(raw_id);
167 if (!model->has_auxiliary_objective(id)) {
169 << "no auxiliary objective with id " << raw_id << " exists";
170 }
171 result[Objective::Auxiliary(model, id)] = value;
172 }
173 return result;
174}
175
176google::protobuf::Map<int64_t, double> AuxiliaryObjectiveValuesToProto(
177 const absl::flat_hash_map<Objective, double>& aux_obj_values) {
178 google::protobuf::Map<int64_t, double> result;
179 for (const auto& [objective, value] : aux_obj_values) {
180 CHECK(objective.id().has_value())
181 << "encountered primary objective in auxiliary objective value map";
182 result[objective.id().value()] = value;
183 }
184 return result;
185}
186
187absl::StatusOr<LinearConstraintMap<double>> LinearConstraintValuesFromProto(
188 const ModelStorageCPtr model,
189 const SparseDoubleVectorProto& lin_cons_proto) {
190 RETURN_IF_ERROR(CheckSparseVectorProto(lin_cons_proto));
191 RETURN_IF_ERROR(LinearConstraintIdsExist(model, lin_cons_proto.ids()));
192 return MakeView(lin_cons_proto).as_map<LinearConstraint>(model);
193}
194
196 const LinearConstraintMap<double>& linear_constraint_values) {
197 return MapToProto(linear_constraint_values);
198}
199
200absl::StatusOr<absl::flat_hash_map<QuadraticConstraint, double>>
202 const ModelStorageCPtr model,
203 const SparseDoubleVectorProto& quad_cons_proto) {
204 RETURN_IF_ERROR(CheckSparseVectorProto(quad_cons_proto));
205 RETURN_IF_ERROR(QuadraticConstraintIdsExist(model, quad_cons_proto.ids()));
206 return MakeView(quad_cons_proto).as_map<QuadraticConstraint>(model);
207}
208
210 const absl::flat_hash_map<QuadraticConstraint, double>&
211 quadratic_constraint_values) {
212 return MapToProto(quadratic_constraint_values);
213}
214
215absl::StatusOr<VariableMap<BasisStatus>> VariableBasisFromProto(
216 const ModelStorageCPtr model, const SparseBasisStatusVector& basis_proto) {
217 RETURN_IF_ERROR(CheckSparseVectorProto(basis_proto));
218 RETURN_IF_ERROR(VariableIdsExist(model, basis_proto.ids()));
219 return BasisVectorFromProto<Variable>(model, basis_proto);
220}
221
223 const VariableMap<BasisStatus>& basis_values) {
224 return BasisMapToProto(basis_values);
225}
226
227absl::StatusOr<LinearConstraintMap<BasisStatus>> LinearConstraintBasisFromProto(
228 const ModelStorageCPtr model, const SparseBasisStatusVector& basis_proto) {
229 RETURN_IF_ERROR(CheckSparseVectorProto(basis_proto));
230 RETURN_IF_ERROR(LinearConstraintIdsExist(model, basis_proto.ids()));
231 return BasisVectorFromProto<LinearConstraint>(model, basis_proto);
232}
233
235 const LinearConstraintMap<BasisStatus>& basis_values) {
236 return BasisMapToProto(basis_values);
237}
238
239} // namespace operations_research::math_opt
#define RETURN_IF_ERROR(expr)
static Objective Auxiliary(ModelStorageCPtr storage, AuxiliaryObjectiveId id)
Returns an object that refers to an auxiliary objective of the model.
Definition objective.h:219
An object oriented wrapper for quadratic constraints in ModelStorage.
Definition gurobi_isv.cc:28
google::protobuf::Map< int64_t, double > AuxiliaryObjectiveValuesToProto(const absl::flat_hash_map< Objective, double > &aux_obj_values)
absl::Status CheckIdsAndValuesSize(const SparseVectorView< T > &vector_view, absl::string_view value_name="values")
absl::flat_hash_map< Variable, V > VariableMap
absl::Nonnull< const ModelStorage * > ModelStorageCPtr
absl::flat_hash_map< LinearConstraint, V > LinearConstraintMap
SparseDoubleVectorProto LinearConstraintValuesToProto(const LinearConstraintMap< double > &linear_constraint_values)
Returns the proto equivalent of linear_constraint_values.
ElementId< ElementType::kAuxiliaryObjective > AuxiliaryObjectiveId
Definition elements.h:266
absl::StatusOr< LinearConstraintMap< double > > LinearConstraintValuesFromProto(const ModelStorageCPtr model, const SparseDoubleVectorProto &lin_cons_proto)
absl::StatusOr< absl::flat_hash_map< Objective, double > > AuxiliaryObjectiveValuesFromProto(const ModelStorageCPtr model, const google::protobuf::Map< int64_t, double > &aux_obj_proto)
std::optional< typename EnumProto< P >::Cpp > EnumFromProto(P proto_value)
Definition enums.h:281
ElementId< ElementType::kVariable > VariableId
Definition elements.h:264
SparseBasisStatusVector VariableBasisToProto(const VariableMap< BasisStatus > &basis_values)
Returns the proto equivalent of basis_values.
absl::StatusOr< LinearConstraintMap< BasisStatus > > LinearConstraintBasisFromProto(const ModelStorageCPtr model, const SparseBasisStatusVector &basis_proto)
absl::StatusOr< absl::flat_hash_map< QuadraticConstraint, double > > QuadraticConstraintValuesFromProto(const ModelStorageCPtr model, const SparseDoubleVectorProto &quad_cons_proto)
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
ElementId< ElementType::kQuadraticConstraint > QuadraticConstraintId
Definition elements.h:267
SparseBasisStatusVector LinearConstraintBasisToProto(const LinearConstraintMap< BasisStatus > &basis_values)
Returns the proto equivalent of basis_values.
SparseDoubleVectorProto VariableValuesToProto(const VariableMap< double > &variable_values)
Returns the proto equivalent of variable_values.
ElementId< ElementType::kLinearConstraint > LinearConstraintId
Definition elements.h:265
absl::StatusOr< VariableMap< BasisStatus > > VariableBasisFromProto(const ModelStorageCPtr model, const SparseBasisStatusVector &basis_proto)
SparseDoubleVectorProto QuadraticConstraintValuesToProto(const absl::flat_hash_map< QuadraticConstraint, double > &quadratic_constraint_values)
Returns the proto equivalent of quadratic_constraint_values.
Enum< E >::Proto EnumToProto(std::optional< E > value)
Definition enums.h:270
absl::StatusOr< VariableMap< double > > VariableValuesFromProto(const ModelStorageCPtr model, const SparseDoubleVectorProto &vars_proto)
absl::Status CheckIdsRangeAndStrictlyIncreasing(absl::Span< const int64_t > ids)
StatusBuilder InvalidArgumentErrorBuilder()