OR-Tools  9.6
sparse_containers.cc
Go to the documentation of this file.
1 // Copyright 2010-2022 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 <optional>
17 
19 namespace {
20 
21 // SparseVectorProtoType should be SparseDoubleVector or SparseBasisStatusVector
22 template <typename SparseVectorProtoType>
23 absl::Status CheckSparseVectorProto(const SparseVectorProtoType& vec) {
26  return absl::OkStatus();
27 }
28 
29 template <typename Key>
30 absl::StatusOr<IdMap<Key, BasisStatus>> BasisVectorFromProto(
31  const ModelStorage* const model,
32  const SparseBasisStatusVector& basis_proto) {
33  using IdType = typename Key::IdType;
34  absl::flat_hash_map<IdType, BasisStatus> raw_map;
35  raw_map.reserve(basis_proto.ids_size());
36  for (const auto& [id, basis_status_proto_int] : MakeView(basis_proto)) {
37  const auto basis_status_proto =
38  static_cast<BasisStatusProto>(basis_status_proto_int);
39  const std::optional<BasisStatus> basis_status =
40  EnumFromProto(basis_status_proto);
41  if (!basis_status.has_value()) {
43  << "basis status not specified for id " << id;
44  }
45  raw_map[IdType(id)] = *basis_status;
46  }
47  return IdMap<Key, BasisStatus>(model, std::move(raw_map));
48 }
49 
50 template <typename Key>
51 SparseDoubleVectorProto IdMapToProto(const IdMap<Key, double>& id_map) {
52  using IdType = typename Key::IdType;
53  SparseDoubleVectorProto result;
54  std::vector<std::pair<IdType, double>> sorted_entries(
55  id_map.raw_map().begin(), id_map.raw_map().end());
56  std::sort(sorted_entries.begin(), sorted_entries.end());
57  for (const auto& [id, val] : sorted_entries) {
58  result.add_ids(id.value());
59  result.add_values(val);
60  }
61  return result;
62 }
63 
64 template <typename Key>
65 SparseBasisStatusVector BasisIdMapToProto(
66  const IdMap<Key, BasisStatus>& basis_map) {
67  using IdType = typename Key::IdType;
68  SparseBasisStatusVector result;
69  std::vector<std::pair<IdType, BasisStatus>> sorted_entries(
70  basis_map.raw_map().begin(), basis_map.raw_map().end());
71  std::sort(sorted_entries.begin(), sorted_entries.end());
72  for (const auto& [id, val] : sorted_entries) {
73  result.add_ids(id.value());
74  result.add_values(EnumToProto(val));
75  }
76  return result;
77 }
78 
79 absl::Status VariableIdsExist(const ModelStorage* const model,
80  const absl::Span<const int64_t> ids) {
81  for (const int64_t id : ids) {
82  if (!model->has_variable(VariableId(id))) {
84  << "no variable with id " << id << " exists";
85  }
86  }
87  return absl::OkStatus();
88 }
89 
90 absl::Status LinearConstraintIdsExist(const ModelStorage* const model,
91  const absl::Span<const int64_t> ids) {
92  for (const int64_t id : ids) {
93  if (!model->has_linear_constraint(LinearConstraintId(id))) {
95  << "no linear constraint with id " << id << " exists";
96  }
97  }
98  return absl::OkStatus();
99 }
100 
101 } // namespace
102 
103 absl::StatusOr<VariableMap<double>> VariableValuesFromProto(
104  const ModelStorage* const model,
105  const SparseDoubleVectorProto& vars_proto) {
106  RETURN_IF_ERROR(CheckSparseVectorProto(vars_proto));
107  RETURN_IF_ERROR(VariableIdsExist(model, vars_proto.ids()));
108  return VariableMap<double>(model, MakeView(vars_proto).as_map<VariableId>());
109 }
110 
111 SparseDoubleVectorProto VariableValuesToProto(
112  const VariableMap<double>& variable_values) {
113  return IdMapToProto(variable_values);
114 }
115 
116 absl::StatusOr<LinearConstraintMap<double>> LinearConstraintValuesFromProto(
117  const ModelStorage* const model,
118  const SparseDoubleVectorProto& lin_cons_proto) {
119  RETURN_IF_ERROR(CheckSparseVectorProto(lin_cons_proto));
120  RETURN_IF_ERROR(LinearConstraintIdsExist(model, lin_cons_proto.ids()));
122  model, MakeView(lin_cons_proto).as_map<LinearConstraintId>());
123 }
124 
125 SparseDoubleVectorProto LinearConstraintValuesToProto(
126  const LinearConstraintMap<double>& linear_constraint_values) {
127  return IdMapToProto(linear_constraint_values);
128 }
129 
130 absl::StatusOr<VariableMap<BasisStatus>> VariableBasisFromProto(
131  const ModelStorage* const model,
132  const SparseBasisStatusVector& basis_proto) {
133  RETURN_IF_ERROR(CheckSparseVectorProto(basis_proto));
134  RETURN_IF_ERROR(VariableIdsExist(model, basis_proto.ids()));
135  return BasisVectorFromProto<Variable>(model, basis_proto);
136 }
137 
138 SparseBasisStatusVector VariableBasisToProto(
139  const VariableMap<BasisStatus>& basis_values) {
140  return BasisIdMapToProto(basis_values);
141 }
142 
143 absl::StatusOr<LinearConstraintMap<BasisStatus>> LinearConstraintBasisFromProto(
144  const ModelStorage* const model,
145  const SparseBasisStatusVector& basis_proto) {
146  RETURN_IF_ERROR(CheckSparseVectorProto(basis_proto));
147  RETURN_IF_ERROR(LinearConstraintIdsExist(model, basis_proto.ids()));
148  return BasisVectorFromProto<LinearConstraint>(model, basis_proto);
149 }
150 
151 SparseBasisStatusVector LinearConstraintBasisToProto(
152  const LinearConstraintMap<BasisStatus>& basis_values) {
153  return BasisIdMapToProto(basis_values);
154 }
155 
156 } // namespace operations_research::math_opt
#define RETURN_IF_ERROR(expr)
int64_t value
GRBmodel * model
absl::Status CheckIdsAndValuesSize(const SparseVectorView< T > &vector_view, absl::string_view value_name="values")
SparseBasisStatusVector VariableBasisToProto(const VariableMap< BasisStatus > &basis_values)
SparseBasisStatusVector LinearConstraintBasisToProto(const LinearConstraintMap< BasisStatus > &basis_values)
absl::StatusOr< LinearConstraintMap< double > > LinearConstraintValuesFromProto(const ModelStorage *const model, const SparseDoubleVectorProto &lin_cons_proto)
SparseDoubleVectorProto LinearConstraintValuesToProto(const LinearConstraintMap< double > &linear_constraint_values)
absl::Status CheckIdsRangeAndStrictlyIncreasing(absl::Span< const int64_t > ids)
absl::StatusOr< VariableMap< BasisStatus > > VariableBasisFromProto(const ModelStorage *const model, const SparseBasisStatusVector &basis_proto)
absl::StatusOr< VariableMap< double > > VariableValuesFromProto(const ModelStorage *const model, const SparseDoubleVectorProto &vars_proto)
SparseDoubleVectorProto VariableValuesToProto(const VariableMap< double > &variable_values)
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
std::optional< typename EnumProto< P >::Cpp > EnumFromProto(const P proto_value)
Definition: enums.h:279
absl::StatusOr< LinearConstraintMap< BasisStatus > > LinearConstraintBasisFromProto(const ModelStorage *const model, const SparseBasisStatusVector &basis_proto)
Enum< E >::Proto EnumToProto(const std::optional< E > value)
Definition: enums.h:268
StatusBuilder InvalidArgumentErrorBuilder()