24#include "absl/base/optimization.h"
25#include "absl/container/flat_hash_set.h"
26#include "absl/log/check.h"
27#include "absl/log/log.h"
28#include "absl/status/status.h"
29#include "absl/strings/string_view.h"
45constexpr double kInf = std::numeric_limits<double>::infinity();
56 return objective_bounds;
70 return problem_status;
78 for (
const auto [
id, value] :
MakeView(sparse_vector)) {
81 if (!(value == 0.0)) {
82 sparse_vector.
set_ids(next,
id);
101 const auto& ids = filter_.filtered_ids();
102 CHECK(std::adjacent_find(ids.begin(), ids.end(),
103 std::greater_equal<int64_t>()) == ids.end())
104 <<
"The input filter.filtered_ids must be strictly increasing.";
126 *
solution.mutable_primal_solution()->mutable_variable_values() =
132 *
solution.mutable_dual_solution()->mutable_dual_values() =
138 *
solution.mutable_dual_solution()->mutable_reduced_costs() =
149 absl::flat_hash_set<CallbackEventProto> events;
157 const absl::string_view
detail) {
172 const absl::string_view
detail) {
177 const absl::string_view
detail) {
182 const absl::string_view
detail) {
199ObjectiveBoundsProto MakeUnboundedBounds(
const bool is_maximize) {
200 ObjectiveBoundsProto bounds;
202 bounds.set_dual_bound(bounds.primal_bound());
209 const absl::string_view
detail) {
224 const double dual_objective,
225 const absl::string_view
detail) {
240 const absl::string_view
detail) {
256 const absl::string_view
detail) {
274 const bool is_maximize,
const LimitProto limit,
275 const std::optional<double> optional_finite_primal_objective,
276 const std::optional<double> optional_dual_objective,
277 const absl::string_view
detail) {
278 if (optional_finite_primal_objective.has_value()) {
280 *optional_finite_primal_objective,
281 optional_dual_objective,
detail);
284 optional_dual_objective,
detail);
288 LimitProto limit,
const double primal_objective,
289 const double dual_objective,
const bool claim_dual_feasible_solution_exists,
290 const absl::string_view
detail) {
292 if (std::isfinite(primal_objective)) {
301 if (claim_dual_feasible_solution_exists) {
318 const absl::string_view
detail) {
325 const bool is_maximize,
const LimitProto limit,
326 const std::optional<double> optional_dual_objective,
327 const absl::string_view
detail) {
335 if (optional_dual_objective.has_value()) {
348 const bool is_maximize,
const LimitProto limit,
349 const double primal_objective,
350 const std::optional<double> optional_dual_objective,
351 const absl::string_view
detail) {
360 if (optional_dual_objective.has_value()) {
374 const absl::string_view
detail) {
392 const absl::string_view solver_name) {
393 const auto error_status = [solver_name](
394 const absl::string_view structure,
399 << solver_name <<
" does not support " << structure;
402 <<
"MathOpt does not currently support " << solver_name
403 <<
" models with " << structure;
405 LOG(FATAL) <<
"Unexpected call with `kSupported`";
413 return error_status(
"integer variables", support);
420 return error_status(
"multiple objectives", support);
426 return error_status(
"quadratic objectives", support);
429 if (!objective.quadratic_coefficients().row_ids().empty()) {
430 return error_status(
"quadratic objectives", support);
437 return error_status(
"quadratic constraints", support);
443 return error_status(
"second-order cone constraints", support);
449 return error_status(
"sos1 constraints", support);
455 return error_status(
"sos2 constraints", support);
461 return error_status(
"indicator constraints", support);
464 return absl::OkStatus();
470 for (
const bool is_integer :
498 for (
const auto& [_, new_objective] :
500 if (!new_objective.quadratic_coefficients().row_ids().empty()) {
504 for (
const auto& [_, objective_update] :
506 if (!objective_update.quadratic_coefficients().row_ids().empty()) {
513 const auto contains_new_or_deleted_constraints =
514 [](
const auto& constraint_update) {
515 return !constraint_update.new_constraints().empty() ||
516 !constraint_update.deleted_constraint_ids().empty();
519 if (contains_new_or_deleted_constraints(
525 if (contains_new_or_deleted_constraints(
541 if (contains_new_or_deleted_constraints(
552 const absl::string_view solver_name) {
553 const auto validate_support = [solver_name](
554 const absl::string_view structure,
558 return absl::OkStatus();
561 << structure <<
" is not supported as " << solver_name
562 <<
" does not support multiple objectives";
566 <<
" is not supported as MathOpt does not currently support "
567 << solver_name <<
" models with multiple objectives";
569 return absl::OkStatus();
573 "ModelSolveParametersProto.primary_objective_parameters",
578 "ModelSolveParametersProto.auxiliary_objective_parameters",
581 return absl::OkStatus();
#define RETURN_IF_ERROR(expr)
::int64_t deleted_objective_ids(int index) const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveProto > & new_objectives() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveUpdatesProto > & objective_updates() const
::operations_research::math_opt::CallbackEventProto request_registration(int index) const
int request_registration_size() const
const ::operations_research::math_opt::VariablesProto & variables() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::QuadraticConstraintProto > & quadratic_constraints() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SosConstraintProto > & sos1_constraints() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SosConstraintProto > & sos2_constraints() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::SecondOrderConeConstraintProto > & second_order_cone_constraints() const
const ::operations_research::math_opt::ObjectiveProto & objective() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveProto > & auxiliary_objectives() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::IndicatorConstraintProto > & indicator_constraints() const
const ::operations_research::math_opt::SparseVectorFilterProto & variable_values_filter() const
bool has_dual_values_filter() const
bool has_reduced_costs_filter() const
const ::operations_research::math_opt::SparseVectorFilterProto & reduced_costs_filter() const
const ::operations_research::math_opt::SparseVectorFilterProto & dual_values_filter() const
bool has_primary_objective_parameters() const
bool has_variable_values_filter() const
const ::google::protobuf::Map<::int64_t, ::operations_research::math_opt::ObjectiveParametersProto > & auxiliary_objective_parameters() const
const ::operations_research::math_opt::SosConstraintUpdatesProto & sos1_constraint_updates() const
const ::operations_research::math_opt::AuxiliaryObjectivesUpdatesProto & auxiliary_objectives_updates() const
const ::operations_research::math_opt::VariableUpdatesProto & variable_updates() const
const ::operations_research::math_opt::QuadraticConstraintUpdatesProto & quadratic_constraint_updates() const
const ::operations_research::math_opt::SosConstraintUpdatesProto & sos2_constraint_updates() const
const ::operations_research::math_opt::IndicatorConstraintUpdatesProto & indicator_constraint_updates() const
const ::operations_research::math_opt::ObjectiveUpdatesProto & objective_updates() const
const ::operations_research::math_opt::SecondOrderConeConstraintUpdatesProto & second_order_cone_constraint_updates() const
const ::operations_research::math_opt::VariablesProto & new_variables() const
void set_dual_bound(double value)
double dual_bound() const
void set_primal_bound(double value)
double primal_bound() const
const ::operations_research::math_opt::SparseDoubleMatrixProto & quadratic_coefficients() const
const ::operations_research::math_opt::SparseDoubleMatrixProto & quadratic_coefficients() const
void set_primal_status(::operations_research::math_opt::FeasibilityStatusProto value)
::operations_research::math_opt::FeasibilityStatusProto dual_status() const
void set_primal_or_dual_infeasible(bool value)
bool primal_or_dual_infeasible() const
void set_dual_status(::operations_research::math_opt::FeasibilityStatusProto value)
::operations_research::math_opt::FeasibilityStatusProto primal_status() const
::operations_research::math_opt::TerminationProto *PROTOBUF_NONNULL mutable_termination()
const ::operations_research::math_opt::SolveStatsProto & solve_stats() const
::operations_research::math_opt::SolveStatsProto *PROTOBUF_NONNULL mutable_solve_stats()
const ::operations_research::math_opt::TerminationProto & termination() const
const ::operations_research::math_opt::ProblemStatusProto & problem_status() const
double best_primal_bound() const
void set_best_dual_bound(double value)
::operations_research::math_opt::ProblemStatusProto *PROTOBUF_NONNULL mutable_problem_status()
double best_dual_bound() const
void set_best_primal_bound(double value)
bool values(int index) const
::int64_t row_ids(int index) const
::google::protobuf::RepeatedField<::int64_t > *PROTOBUF_NONNULL mutable_ids()
void add_ids(::int64_t value)
void set_ids(int index, ::int64_t value)
void set_values(int index, double value)
void add_values(double value)
::google::protobuf::RepeatedField< double > *PROTOBUF_NONNULL mutable_values()
SparseVectorFilterPredicate(const SparseVectorFilterProto &filter)
bool AcceptsAndUpdate(int64_t id, const Value &value)
bool has_problem_status() const
const ::operations_research::math_opt::ObjectiveBoundsProto & objective_bounds() const
void set_limit(::operations_research::math_opt::LimitProto value)
void set_detail(Arg_ &&arg, Args_... args)
::operations_research::math_opt::ObjectiveBoundsProto *PROTOBUF_NONNULL mutable_objective_bounds()
::operations_research::math_opt::ProblemStatusProto *PROTOBUF_NONNULL mutable_problem_status()
bool has_objective_bounds() const
const ::operations_research::math_opt::ProblemStatusProto & problem_status() const
void set_reason(::operations_research::math_opt::TerminationReasonProto value)
const ::operations_research::math_opt::SparseBoolVectorProto & integers() const
bool integers(int index) const
TerminationProto TerminateForReason(const TerminationReasonProto reason, const absl::string_view detail)
absl::Status ModelIsSupported(const ModelProto &model, const SupportedProblemStructures &support_menu, const absl::string_view solver_name)
@ TERMINATION_REASON_OPTIMAL
@ TERMINATION_REASON_INFEASIBLE_OR_UNBOUNDED
@ TERMINATION_REASON_NO_SOLUTION_FOUND
@ TERMINATION_REASON_FEASIBLE
@ TERMINATION_REASON_INFEASIBLE
@ TERMINATION_REASON_UNBOUNDED
TerminationProto FeasibleTermination(const LimitProto limit, const absl::string_view detail)
void UpgradeSolveResultProtoForStatsMigration(SolveResultProto &solve_result_proto)
TerminationProto TerminateForLimit(const LimitProto limit, const bool feasible, const absl::string_view detail)
absl::Status ModelSolveParametersAreSupported(const ModelSolveParametersProto &model_parameters, const SupportedProblemStructures &support_menu, const absl::string_view solver_name)
absl::flat_hash_set< CallbackEventProto > EventSet(const CallbackRegistrationProto &callback_registration)
TerminationProto OptimalTerminationProto(const double finite_primal_objective, const double dual_objective, const absl::string_view detail)
@ FEASIBILITY_STATUS_FEASIBLE
@ FEASIBILITY_STATUS_UNDETERMINED
@ FEASIBILITY_STATUS_INFEASIBLE
TerminationProto LimitTerminationProto(const bool is_maximize, const LimitProto limit, const std::optional< double > optional_finite_primal_objective, const std::optional< double > optional_dual_objective, const absl::string_view detail)
TerminationProto InfeasibleOrUnboundedTerminationProto(bool is_maximize, const FeasibilityStatusProto dual_feasibility_status, const absl::string_view detail)
bool UpdateIsSupported(const ModelUpdateProto &update, const SupportedProblemStructures &support_menu)
ProblemStatusProto GetProblemStatus(const SolveResultProto &solve_result)
TerminationProto FeasibleTerminationProto(const bool is_maximize, const LimitProto limit, const double primal_objective, const std::optional< double > optional_dual_objective, const absl::string_view detail)
ObjectiveBoundsProto GetObjectiveBounds(const SolveResultProto &solve_result)
TerminationProto NoSolutionFoundTerminationProto(const bool is_maximize, const LimitProto limit, const std::optional< double > optional_dual_objective, const absl::string_view detail)
SparseVectorView< T > MakeView(absl::Span< const int64_t > ids, const Collection &values)
TerminationProto NoSolutionFoundTermination(const LimitProto limit, const absl::string_view detail)
TerminationProto InfeasibleTerminationProto(bool is_maximize, const FeasibilityStatusProto dual_feasibility_status, const absl::string_view detail)
SparseDoubleVectorProto FilterSparseVector(const SparseDoubleVectorProto &input, const SparseVectorFilterProto &filter)
TerminationProto CutoffTerminationProto(bool is_maximize, const absl::string_view detail)
TerminationProto UnboundedTerminationProto(const bool is_maximize, const absl::string_view detail)
void RemoveSparseDoubleVectorZeros(SparseDoubleVectorProto &sparse_vector)
void ApplyAllFilters(const ModelSolveParametersProto &model_solve_params, SolutionProto &solution)
ObjectiveBoundsProto MakeTrivialBounds(const bool is_maximize)
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
StatusBuilder UnimplementedErrorBuilder()
StatusBuilder InvalidArgumentErrorBuilder()
static int input(yyscan_t yyscanner)
SupportType second_order_cone_constraints
SupportType sos2_constraints
SupportType quadratic_objectives
SupportType multi_objectives
SupportType integer_variables
SupportType sos1_constraints
SupportType quadratic_constraints
SupportType indicator_constraints