24#include "absl/container/flat_hash_set.h"
25#include "absl/log/check.h"
26#include "absl/log/log.h"
27#include "absl/status/status.h"
28#include "absl/strings/string_view.h"
44constexpr double kInf = std::numeric_limits<double>::infinity();
55 return objective_bounds;
69 return problem_status;
77 for (
const auto [
id, value] :
MakeView(sparse_vector)) {
80 if (!(value == 0.0)) {
81 sparse_vector.
set_ids(next,
id);
100 const auto& ids = filter_.filtered_ids();
101 CHECK(std::adjacent_find(ids.begin(), ids.end(),
102 std::greater_equal<int64_t>()) == ids.end())
103 <<
"The input filter.filtered_ids must be strictly increasing.";
125 *
solution.mutable_primal_solution()->mutable_variable_values() =
131 *
solution.mutable_dual_solution()->mutable_dual_values() =
137 *
solution.mutable_dual_solution()->mutable_reduced_costs() =
148 absl::flat_hash_set<CallbackEventProto> events;
156 const absl::string_view
detail) {
171 const absl::string_view
detail) {
176 const absl::string_view
detail) {
181 const absl::string_view
detail) {
198ObjectiveBoundsProto MakeUnboundedBounds(
const bool is_maximize) {
199 ObjectiveBoundsProto bounds;
201 bounds.set_dual_bound(bounds.primal_bound());
208 const absl::string_view
detail) {
223 const double dual_objective,
224 const absl::string_view
detail) {
239 const absl::string_view
detail) {
255 const absl::string_view
detail) {
273 const bool is_maximize,
const LimitProto limit,
274 const std::optional<double> optional_finite_primal_objective,
275 const std::optional<double> optional_dual_objective,
276 const absl::string_view
detail) {
277 if (optional_finite_primal_objective.has_value()) {
279 *optional_finite_primal_objective,
280 optional_dual_objective,
detail);
283 optional_dual_objective,
detail);
287 LimitProto limit,
const double primal_objective,
288 const double dual_objective,
const bool claim_dual_feasible_solution_exists,
289 const absl::string_view
detail) {
291 if (std::isfinite(primal_objective)) {
300 if (claim_dual_feasible_solution_exists) {
317 const absl::string_view
detail) {
324 const bool is_maximize,
const LimitProto limit,
325 const std::optional<double> optional_dual_objective,
326 const absl::string_view
detail) {
334 if (optional_dual_objective.has_value()) {
347 const bool is_maximize,
const LimitProto limit,
348 const double primal_objective,
349 const std::optional<double> optional_dual_objective,
350 const absl::string_view
detail) {
359 if (optional_dual_objective.has_value()) {
373 const absl::string_view
detail) {
391 const absl::string_view solver_name) {
392 const auto error_status = [solver_name](
393 const absl::string_view structure,
398 << solver_name <<
" does not support " << structure;
401 <<
"MathOpt does not currently support " << solver_name
402 <<
" models with " << structure;
404 LOG(FATAL) <<
"Unexpected call with `kSupported`";
411 return error_status(
"integer variables", support);
418 return error_status(
"multiple objectives", support);
424 return error_status(
"quadratic objectives", support);
427 if (!objective.quadratic_coefficients().row_ids().empty()) {
428 return error_status(
"quadratic objectives", support);
435 return error_status(
"quadratic constraints", support);
441 return error_status(
"second-order cone constraints", support);
447 return error_status(
"sos1 constraints", support);
453 return error_status(
"sos2 constraints", support);
459 return error_status(
"indicator constraints", support);
462 return absl::OkStatus();
468 for (
const bool is_integer :
496 for (
const auto& [_, new_objective] :
498 if (!new_objective.quadratic_coefficients().row_ids().empty()) {
502 for (
const auto& [_, objective_update] :
504 if (!objective_update.quadratic_coefficients().row_ids().empty()) {
511 const auto contains_new_or_deleted_constraints =
512 [](
const auto& constraint_update) {
513 return !constraint_update.new_constraints().empty() ||
514 !constraint_update.deleted_constraint_ids().empty();
517 if (contains_new_or_deleted_constraints(
523 if (contains_new_or_deleted_constraints(
539 if (contains_new_or_deleted_constraints(
550 const absl::string_view solver_name) {
551 const auto validate_support = [solver_name](
552 const absl::string_view structure,
556 return absl::OkStatus();
559 << structure <<
" is not supported as " << solver_name
560 <<
" does not support multiple objectives";
564 <<
" is not supported as MathOpt does not currently support "
565 << solver_name <<
" models with multiple objectives";
567 return absl::OkStatus();
571 "ModelSolveParametersProto.primary_objective_parameters",
576 "ModelSolveParametersProto.auxiliary_objective_parameters",
579 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
repeated .operations_research.math_opt.CallbackEventProto request_registration = 1;
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
.operations_research.math_opt.SparseVectorFilterProto dual_values_filter = 2;
bool has_reduced_costs_filter() const
.operations_research.math_opt.SparseVectorFilterProto reduced_costs_filter = 3;
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
.operations_research.math_opt.ObjectiveParametersProto primary_objective_parameters = 7;
bool has_variable_values_filter() const
.operations_research.math_opt.SparseVectorFilterProto variable_values_filter = 1;
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
int ids_size() const
repeated int64 ids = 1;
::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)
int values_size() const
repeated double values = 2;
::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
.operations_research.math_opt.ProblemStatusProto problem_status = 4;
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
.operations_research.math_opt.ObjectiveBoundsProto objective_bounds = 5;
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
An object oriented wrapper for quadratic constraints in ModelStorage.
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)
Returns the callback_registration.request_registration as a set of enums.
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 CutoffTerminationProto(bool is_maximize, const absl::string_view detail)
Calls NoSolutionFoundTerminationProto() with LIMIT_CUTOFF LIMIT.
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 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)
In SWIG mode, we don't want anything besides these top-level includes.
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