21#include "absl/container/flat_hash_map.h"
22#include "absl/status/status.h"
23#include "absl/status/statusor.h"
24#include "absl/strings/string_view.h"
25#include "absl/time/time.h"
26#include "absl/types/span.h"
32#include "ortools/math_opt/solution.pb.h"
45template <
typename TypedIndex>
46absl::flat_hash_map<TypedIndex, BasisStatus> BasisStatusMapFromProto(
47 const absl::flat_hash_map<TypedIndex, BasisStatusProto>& proto_map) {
48 absl::flat_hash_map<TypedIndex, BasisStatus> cpp_map;
49 for (
const auto& [
id, proto_value] : proto_map) {
50 const std::optional<BasisStatus> opt_status =
EnumFromProto(proto_value);
51 CHECK(opt_status.has_value());
52 cpp_map.emplace(
id, *opt_status);
63 return "undetermined";
78 return absl::MakeConstSpan(kFeasibilityStatus);
91 return "infeasible_or_unbounded";
97 return "no_solution_found";
99 return "numerical_error";
101 return "other_error";
118 return absl::MakeConstSpan(kTerminationReasonValues);
124 return "undetermined";
142 return "interrupted";
144 return "slow_progress";
152 static constexpr Limit kLimitValues[] = {
157 return absl::MakeConstSpan(kLimitValues);
161 : reason(reason), detail(
std::move(detail)) {}
170 const std::string detail) {
177 TerminationProto
proto;
179 if (
limit.has_value()) {
193 termination_proto.reason() == TERMINATION_REASON_FEASIBLE ||
194 termination_proto.reason() == TERMINATION_REASON_NO_SOLUTION_FOUND;
195 const bool has_limit = termination_proto.limit() != LIMIT_UNSPECIFIED;
197 <<
"Termination reason should be TERMINATION_REASON_FEASIBLE or "
198 "TERMINATION_REASON_NO_SOLUTION_FOUND if and only if limit is "
199 "specified, but found reason="
204 const std::optional<Limit> opt_limit =
206 CHECK(opt_limit.has_value());
207 if (termination_proto.reason() == TERMINATION_REASON_FEASIBLE) {
208 return Feasible(*opt_limit, termination_proto.detail());
213 const std::optional<TerminationReason> opt_reason =
215 CHECK(opt_reason.has_value());
216 return Termination(*opt_reason, termination_proto.detail());
220 ostr <<
"{reason: " << termination.
reason;
221 if (termination.
limit.has_value()) {
222 ostr <<
", limit: " << *termination.
limit;
224 if (!termination.
detail.empty()) {
226 ostr <<
", detail: " << termination.
detail;
233 std::ostringstream stream;
239 ProblemStatusProto
proto;
247 const ProblemStatusProto& problem_status_proto) {
250 const std::optional<FeasibilityStatus> opt_primal_status =
252 const std::optional<FeasibilityStatus> opt_dual_status =
254 CHECK(opt_primal_status.has_value());
255 CHECK(opt_dual_status.has_value());
256 result.primal_status = *opt_primal_status;
257 result.dual_status = *opt_dual_status;
258 result.primal_or_dual_infeasible =
259 problem_status_proto.primal_or_dual_infeasible();
266 ostr <<
", dual_status: " << problem_status.
dual_status;
267 ostr <<
", primal_or_dual_infeasible: "
274 std::ostringstream stream;
280 SolveStatsProto
proto;
304 result.
node_count = solve_stats_proto.node_count();
309 ostr <<
"{solve_time: " << solve_stats.
solve_time;
316 ostr <<
", node_count: " << solve_stats.
node_count;
322 std::ostringstream stream;
328 const SolveResultProto& solve_result_proto) {
332 for (
const SolutionProto& solution : solve_result_proto.solutions()) {
335 for (
const PrimalRayProto& primal_ray : solve_result_proto.primal_rays()) {
338 for (
const DualRayProto& dual_ray : solve_result_proto.dual_rays()) {
341 if (solve_result_proto.has_gscip_output()) {
343 std::move(solve_result_proto.gscip_output());
350 (
solutions[0].primal_solution->feasibility_status ==
360 return solutions[0].primal_solution->objective_value;
371 return solutions[0].primal_solution->variable_values;
381 (
solutions[0].dual_solution->feasibility_status ==
387 return solutions[0].dual_solution->dual_values;
392 return solutions[0].dual_solution->reduced_costs;
410 return solutions[0].basis->constraint_status;
415 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
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
GScipOutput gscip_solver_specific_output
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
int first_order_iterations
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={})