22#include "absl/container/flat_hash_map.h"
23#include "absl/strings/string_view.h"
24#include "absl/types/span.h"
26#include "ortools/math_opt/solution.pb.h"
28#include "absl/status/status.h"
40template <
typename TypedIndex>
41absl::flat_hash_map<TypedIndex, BasisStatus> BasisStatusMapFromProto(
42 const absl::flat_hash_map<TypedIndex, BasisStatusProto>& proto_map) {
43 absl::flat_hash_map<TypedIndex, BasisStatus> cpp_map;
44 for (
const auto& [
id, proto_value] : proto_map) {
45 const std::optional<BasisStatus> opt_status =
EnumFromProto(proto_value);
46 CHECK(opt_status.has_value());
47 cpp_map.emplace(
id, *opt_status);
58 return "undetermined";
73 return absl::MakeConstSpan(kFeasibilityStatus);
86 return "infeasible_or_unbounded";
92 return "no_solution_found";
94 return "numerical_error";
113 return absl::MakeConstSpan(kTerminationReasonValues);
119 return "undetermined";
137 return "interrupted";
139 return "slow_progress";
147 static constexpr Limit kLimitValues[] = {
152 return absl::MakeConstSpan(kLimitValues);
156 : reason(reason), detail(
std::move(detail)) {}
165 const std::string detail) {
172 TerminationProto
proto;
174 if (
limit.has_value()) {
188 termination_proto.reason() == TERMINATION_REASON_FEASIBLE ||
189 termination_proto.reason() == TERMINATION_REASON_NO_SOLUTION_FOUND;
190 const bool has_limit = termination_proto.limit() != LIMIT_UNSPECIFIED;
192 <<
"Termination reason should be TERMINATION_REASON_FEASIBLE or "
193 "TERMINATION_REASON_NO_SOLUTION_FOUND if and only if limit is "
194 "specified, but found reason="
199 const std::optional<Limit> opt_limit =
201 CHECK(opt_limit.has_value());
202 if (termination_proto.reason() == TERMINATION_REASON_FEASIBLE) {
203 return Feasible(*opt_limit, termination_proto.detail());
208 const std::optional<TerminationReason> opt_reason =
210 CHECK(opt_reason.has_value());
211 return Termination(*opt_reason, termination_proto.detail());
215 ostr <<
"{reason: " << termination.
reason;
216 if (termination.
limit.has_value()) {
217 ostr <<
", limit: " << *termination.
limit;
219 if (!termination.
detail.empty()) {
221 ostr <<
", detail: " << termination.
detail;
228 std::ostringstream stream;
234 ProblemStatusProto
proto;
242 const ProblemStatusProto& problem_status_proto) {
245 const std::optional<FeasibilityStatus> opt_primal_status =
247 const std::optional<FeasibilityStatus> opt_dual_status =
249 CHECK(opt_primal_status.has_value());
250 CHECK(opt_dual_status.has_value());
251 result.primal_status = *opt_primal_status;
252 result.dual_status = *opt_dual_status;
253 result.primal_or_dual_infeasible =
254 problem_status_proto.primal_or_dual_infeasible();
261 ostr <<
", dual_status: " << problem_status.
dual_status;
262 ostr <<
", primal_or_dual_infeasible: "
269 std::ostringstream stream;
275 SolveStatsProto
proto;
297 result.
node_count = solve_stats_proto.node_count();
302 ostr <<
"{solve_time: " << solve_stats.
solve_time;
308 ostr <<
", node_count: " << solve_stats.
node_count;
314 std::ostringstream stream;
320 const SolveResultProto& solve_result_proto) {
322 result.
warnings = {solve_result_proto.warnings().begin(),
323 solve_result_proto.warnings().end()};
326 for (
const SolutionProto& solution : solve_result_proto.solutions()) {
329 for (
const PrimalRayProto& primal_ray : solve_result_proto.primal_rays()) {
332 for (
const DualRayProto& dual_ray : solve_result_proto.dual_rays()) {
340 (
solutions[0].primal_solution->feasibility_status ==
350 return solutions[0].primal_solution->objective_value;
361 return solutions[0].primal_solution->variable_values;
371 (
solutions[0].dual_solution->feasibility_status ==
377 return solutions[0].dual_solution->dual_values;
382 return solutions[0].dual_solution->reduced_costs;
400 return solutions[0].basis->constraint_status;
405 return solutions[0].basis->variable_status;
#define CHECK_EQ(val1, val2)
std::ostream & operator<<(std::ostream &out, const E value)
std::optional< typename EnumProto< P >::Cpp > EnumFromProto(const P proto_value)
Enum< E >::Proto EnumToProto(const std::optional< E > value)
Collection of objects used to extend the Constraint Solver library.
std::string ProtoEnumToString(ProtoEnumType enum_value)
inline ::absl::StatusOr< absl::Duration > DecodeGoogleApiProto(const google::protobuf::Duration &proto)
inline ::absl::StatusOr< google::protobuf::Duration > EncodeGoogleApiProto(absl::Duration d)
static DualRay FromProto(const ModelStorage *model, const DualRayProto &dual_ray_proto)
static std::optional< absl::string_view > ToOptString(E value)
static absl::Span< const E > AllValues()
static PrimalRay FromProto(const ModelStorage *model, const PrimalRayProto &primal_ray_proto)
std::string ToString() const
FeasibilityStatus dual_status
ProblemStatusProto ToProto() const
FeasibilityStatus primal_status
bool primal_or_dual_infeasible
static ProblemStatus FromProto(const ProblemStatusProto &problem_status_proto)
static Solution FromProto(const ModelStorage *model, const SolutionProto &solution_proto)
double best_objective_bound() const
const VariableMap< double > & ray_variable_values() const
const LinearConstraintMap< double > & dual_values() const
const VariableMap< BasisStatus > & variable_status() const
bool has_dual_ray() const
std::vector< std::string > warnings
bool has_dual_feasible_solution() const
const LinearConstraintMap< double > & ray_dual_values() const
std::vector< PrimalRay > primal_rays
double objective_value() const
static SolveResult FromProto(const ModelStorage *model, const SolveResultProto &solve_result_proto)
const VariableMap< double > & ray_reduced_costs() const
const LinearConstraintMap< BasisStatus > & constraint_status() const
std::vector< Solution > solutions
const VariableMap< double > & variable_values() const
const VariableMap< double > & reduced_costs() const
bool has_primal_feasible_solution() const
std::vector< DualRay > dual_rays
std::string ToString() const
ProblemStatus problem_status
static SolveStats FromProto(const SolveStatsProto &solve_stats_proto)
SolveStatsProto ToProto() const
absl::Duration solve_time
std::string ToString() const
TerminationProto ToProto() const
Termination(TerminationReason reason, std::string detail={})
bool limit_reached() const
std::optional< Limit > limit
static Termination FromProto(const TerminationProto &termination_proto)
static Termination Feasible(Limit limit, std::string detail={})
static Termination NoSolutionFound(Limit limit, std::string detail={})