OR-Tools  9.6
solution.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 #include <utility>
18 
19 #include "absl/container/flat_hash_map.h"
20 #include "absl/strings/string_view.h"
21 #include "absl/types/span.h"
22 #include "ortools/base/logging.h"
29 #include "ortools/math_opt/solution.pb.h"
30 #include "ortools/math_opt/sparse_containers.pb.h"
35 
36 namespace operations_research {
37 namespace math_opt {
38 
39 std::optional<absl::string_view> Enum<SolutionStatus>::ToOptString(
41  switch (value) {
43  return "feasible";
45  return "infeasible";
47  return "undetermined";
48  }
49  return std::nullopt;
50 }
51 
52 absl::Span<const SolutionStatus> Enum<SolutionStatus>::AllValues() {
53  static constexpr SolutionStatus kSolutionStatusValues[] = {
57  };
58  return absl::MakeConstSpan(kSolutionStatusValues);
59 }
60 
61 absl::StatusOr<PrimalSolution> PrimalSolution::FromProto(
62  const ModelStorage* model,
63  const PrimalSolutionProto& primal_solution_proto) {
64  PrimalSolution primal_solution;
66  primal_solution.variable_values,
67  VariableValuesFromProto(model, primal_solution_proto.variable_values()),
68  _ << "invalid variable_values");
69  primal_solution.objective_value = primal_solution_proto.objective_value();
70  const std::optional<SolutionStatus> feasibility_status =
71  EnumFromProto(primal_solution_proto.feasibility_status());
72  if (!feasibility_status.has_value()) {
73  return absl::InvalidArgumentError("feasibility_status must be specified");
74  }
75  primal_solution.feasibility_status = *feasibility_status;
76  return primal_solution;
77 }
78 
79 PrimalSolutionProto PrimalSolution::Proto() const {
80  PrimalSolutionProto result;
81  *result.mutable_variable_values() = VariableValuesToProto(variable_values);
82  result.set_objective_value(objective_value);
83  result.set_feasibility_status(EnumToProto(feasibility_status));
84  return result;
85 }
86 
87 absl::StatusOr<PrimalRay> PrimalRay::FromProto(
88  const ModelStorage* model, const PrimalRayProto& primal_ray_proto) {
89  PrimalRay result;
91  result.variable_values,
92  VariableValuesFromProto(model, primal_ray_proto.variable_values()),
93  _ << "invalid variable_values");
94  return result;
95 }
96 
97 PrimalRayProto PrimalRay::Proto() const {
98  PrimalRayProto result;
99  *result.mutable_variable_values() = VariableValuesToProto(variable_values);
100  return result;
101 }
102 
103 absl::StatusOr<DualSolution> DualSolution::FromProto(
104  const ModelStorage* model, const DualSolutionProto& dual_solution_proto) {
105  DualSolution dual_solution;
107  dual_solution.dual_values,
108  LinearConstraintValuesFromProto(model, dual_solution_proto.dual_values()),
109  _ << "invalid dual_values");
111  dual_solution.reduced_costs,
112  VariableValuesFromProto(model, dual_solution_proto.reduced_costs()),
113  _ << "invalid reduced_costs");
114  if (dual_solution_proto.has_objective_value()) {
115  dual_solution.objective_value = dual_solution_proto.objective_value();
116  }
117  const std::optional<SolutionStatus> feasibility_status =
118  EnumFromProto(dual_solution_proto.feasibility_status());
119  if (!feasibility_status.has_value()) {
120  return absl::InvalidArgumentError("feasibility_status must be specified");
121  }
122  dual_solution.feasibility_status = *feasibility_status;
123  return dual_solution;
124 }
125 
126 DualSolutionProto DualSolution::Proto() const {
127  DualSolutionProto result;
128  *result.mutable_dual_values() = LinearConstraintValuesToProto(dual_values);
129  *result.mutable_reduced_costs() = VariableValuesToProto(reduced_costs);
130  if (objective_value.has_value()) {
131  result.set_objective_value(*objective_value);
132  }
133  result.set_feasibility_status(EnumToProto(feasibility_status));
134  return result;
135 }
136 
137 absl::StatusOr<DualRay> DualRay::FromProto(const ModelStorage* model,
138  const DualRayProto& dual_ray_proto) {
139  DualRay result;
141  result.dual_values,
142  LinearConstraintValuesFromProto(model, dual_ray_proto.dual_values()),
143  _ << "invalid dual_values");
145  result.reduced_costs,
146  VariableValuesFromProto(model, dual_ray_proto.reduced_costs()),
147  _ << "invalid reduced_costs");
148  return result;
149 }
150 
151 DualRayProto DualRay::Proto() const {
152  DualRayProto result;
153  *result.mutable_dual_values() = LinearConstraintValuesToProto(dual_values);
154  *result.mutable_reduced_costs() = VariableValuesToProto(reduced_costs);
155  return result;
156 }
157 
158 absl::StatusOr<Basis> Basis::FromProto(const ModelStorage* model,
159  const BasisProto& basis_proto) {
160  Basis basis;
162  basis.constraint_status,
163  LinearConstraintBasisFromProto(model, basis_proto.constraint_status()),
164  _ << "invalid constraint_status");
166  basis.variable_status,
167  VariableBasisFromProto(model, basis_proto.variable_status()),
168  _ << "invalid variable_status");
169  const std::optional<SolutionStatus> basic_dual_feasibility =
170  EnumFromProto(basis_proto.basic_dual_feasibility());
171  if (!basic_dual_feasibility.has_value()) {
172  return absl::InvalidArgumentError(
173  "basic_dual_feasibility for a basis must be specified");
174  }
176  return basis;
177 }
178 
180  const ModelStorage* const expected_storage) const {
182  internal::CheckModelStorage(/*storage=*/variable_status.storage(),
183  /*expected_storage=*/expected_storage))
184  << "invalid variable_status";
186  internal::CheckModelStorage(/*storage=*/constraint_status.storage(),
187  /*expected_storage=*/expected_storage))
188  << "invalid constraint_status";
189  return absl::OkStatus();
190 }
191 
192 BasisProto Basis::Proto() const {
193  BasisProto result;
194  *result.mutable_constraint_status() =
196  *result.mutable_variable_status() = VariableBasisToProto(variable_status);
197  result.set_basic_dual_feasibility(EnumToProto(basic_dual_feasibility));
198  return result;
199 }
200 
201 absl::StatusOr<Solution> Solution::FromProto(
202  const ModelStorage* model, const SolutionProto& solution_proto) {
203  Solution solution;
204  if (solution_proto.has_primal_solution()) {
206  solution.primal_solution,
207  PrimalSolution::FromProto(model, solution_proto.primal_solution()),
208  _ << "invalid primal_solution");
209  }
210  if (solution_proto.has_dual_solution()) {
212  solution.dual_solution,
213  DualSolution::FromProto(model, solution_proto.dual_solution()),
214  _ << "invalid dual_solution");
215  }
216  if (solution_proto.has_basis()) {
217  OR_ASSIGN_OR_RETURN3(solution.basis,
218  Basis::FromProto(model, solution_proto.basis()),
219  _ << "invalid basis");
220  }
221  return solution;
222 }
223 
224 SolutionProto Solution::Proto() const {
225  SolutionProto result;
226  if (primal_solution.has_value()) {
227  *result.mutable_primal_solution() = primal_solution->Proto();
228  }
229  if (dual_solution.has_value()) {
230  *result.mutable_dual_solution() = dual_solution->Proto();
231  }
232  if (basis.has_value()) {
233  *result.mutable_basis() = basis->Proto();
234  }
235  return result;
236 }
237 
238 } // namespace math_opt
239 } // namespace operations_research
#define RETURN_IF_ERROR(expr)
int64_t value
GRBmodel * model
absl::Status CheckModelStorage(const ModelStorage *const storage, const ModelStorage *const expected_storage)
Definition: key_types.h:69
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::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)
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
Collection of objects used to extend the Constraint Solver library.
VariableMap< BasisStatus > variable_status
Definition: solution.h:232
LinearConstraintMap< BasisStatus > constraint_status
Definition: solution.h:231
absl::Status CheckModelStorage(const ModelStorage *expected_storage) const
Definition: solution.cc:179
static absl::StatusOr< Basis > FromProto(const ModelStorage *model, const BasisProto &basis_proto)
Definition: solution.cc:158
static absl::StatusOr< DualRay > FromProto(const ModelStorage *model, const DualRayProto &dual_ray_proto)
Definition: solution.cc:137
LinearConstraintMap< double > dual_values
Definition: solution.h:181
VariableMap< double > reduced_costs
Definition: solution.h:182
static absl::StatusOr< DualSolution > FromProto(const ModelStorage *model, const DualSolutionProto &dual_solution_proto)
Definition: solution.cc:103
LinearConstraintMap< double > dual_values
Definition: solution.h:142
std::optional< double > objective_value
Definition: solution.h:144
static std::optional< absl::string_view > ToOptString(E value)
Definition: basis_status.cc:24
static absl::Span< const E > AllValues()
Definition: basis_status.cc:41
VariableMap< double > variable_values
Definition: solution.h:112
static absl::StatusOr< PrimalRay > FromProto(const ModelStorage *model, const PrimalRayProto &primal_ray_proto)
Definition: solution.cc:87
static absl::StatusOr< PrimalSolution > FromProto(const ModelStorage *model, const PrimalSolutionProto &primal_solution_proto)
Definition: solution.cc:61
PrimalSolutionProto Proto() const
Definition: solution.cc:79
static absl::StatusOr< Solution > FromProto(const ModelStorage *model, const SolutionProto &solution_proto)
Definition: solution.cc:201
std::optional< DualSolution > dual_solution
Definition: solution.h:260
std::optional< PrimalSolution > primal_solution
Definition: solution.h:259
std::optional< Basis > basis
Definition: solution.h:261
#define OR_ASSIGN_OR_RETURN3(lhs, rexpr, error_expression)