14 #ifndef OR_TOOLS_MATH_OPT_STORAGE_MODEL_STORAGE_H_
15 #define OR_TOOLS_MATH_OPT_STORAGE_MODEL_STORAGE_H_
26 #include "absl/container/flat_hash_map.h"
27 #include "absl/container/flat_hash_set.h"
28 #include "absl/meta/type_traits.h"
29 #include "absl/status/status.h"
30 #include "absl/status/statusor.h"
31 #include "absl/strings/string_view.h"
32 #include "absl/log/check.h"
38 #include "ortools/math_opt/model.pb.h"
39 #include "ortools/math_opt/model_update.pb.h"
40 #include "ortools/math_opt/sparse_containers.pb.h"
170 static absl::StatusOr<std::unique_ptr<ModelStorage>>
FromModelProto(
185 std::unique_ptr<ModelStorage>
Clone(
186 std::optional<absl::string_view> new_name = std::nullopt)
const;
188 inline const std::string&
name()
const {
return name_; }
205 bool is_integer, absl::string_view
name =
"");
210 inline const std::string&
variable_name(VariableId
id)
const;
243 std::vector<VariableId>
variables()
const;
267 absl::string_view
name =
"");
318 VariableId variable)
const;
320 LinearConstraintId constraint, VariableId variable)
const;
331 inline std::vector<std::tuple<LinearConstraintId, VariableId, double>>
336 LinearConstraintId constraint)
const;
340 VariableId variable)
const;
352 VariableId first_variable, VariableId second_variable)
const;
354 VariableId variable)
const;
357 VariableId first_variable, VariableId second_variable)
const;
372 VariableId second_variable,
391 inline std::vector<std::tuple<VariableId, VariableId, double>>
408 template <
typename Constra
intData>
410 ConstraintData data);
416 template <
typename IdType>
420 template <
typename IdType>
429 template <
typename IdType>
434 template <
typename IdType>
440 template <
typename IdType>
444 template <
typename IdType>
448 template <
typename IdType>
455 template <
typename IdType>
461 template <
typename IdType>
463 VariableId variable_id)
const;
466 template <
typename IdType>
550 UpdateTrackerId update_tracker)
const;
574 struct UpdateTrackerData {
579 quadratic_constraints,
583 indicator_constraints)
586 dirty_linear_constraints(linear_constraints,
587 dirty_variables.checkpoint),
588 dirty_quadratic_constraints(quadratic_constraints),
589 dirty_sos1_constraints(sos1_constraints),
590 dirty_sos2_constraints(sos2_constraints),
591 dirty_indicator_constraints(indicator_constraints) {}
606 template <
typename Constra
intData>
607 static constexpr
typename AtomicConstraintStorage<ConstraintData>::Diff
609 AtomicConstraintDirtyFieldPtr();
617 VariableStorage::Diff dirty_variables;
618 ObjectiveStorage::Diff dirty_objective;
619 LinearConstraintStorage::Diff dirty_linear_constraints;
620 AtomicConstraintStorage<QuadraticConstraintData>::Diff
621 dirty_quadratic_constraints;
622 AtomicConstraintStorage<Sos1ConstraintData>::Diff dirty_sos1_constraints;
623 AtomicConstraintStorage<Sos2ConstraintData>::Diff dirty_sos2_constraints;
624 AtomicConstraintStorage<IndicatorConstraintData>::Diff
625 dirty_indicator_constraints;
628 auto UpdateAndGetVariableDiffs() {
629 return MakeUpdateDataFieldRange<&UpdateTrackerData::dirty_variables>(
633 auto UpdateAndGetObjectiveDiffs() {
634 return MakeUpdateDataFieldRange<&UpdateTrackerData::dirty_objective>(
638 auto UpdateAndGetLinearConstraintDiffs() {
640 &UpdateTrackerData::dirty_linear_constraints>(
645 void AddVariables(
const VariablesProto&
variables);
648 void AddLinearConstraints(
const LinearConstraintsProto& linear_constraints);
652 void UpdateLinearObjectiveCoefficients(
657 void UpdateQuadraticObjectiveCoefficients(
662 void UpdateLinearConstraintCoefficients(
667 template <
typename Constra
intData>
668 AtomicConstraintStorage<ConstraintData>& constraint_storage();
672 template <
typename Constra
intData>
673 const AtomicConstraintStorage<ConstraintData>& constraint_storage()
const;
677 VariableStorage variables_;
678 ObjectiveStorage objective_;
679 LinearConstraintStorage linear_constraints_;
681 AtomicConstraintStorage<QuadraticConstraintData> quadratic_constraints_;
682 AtomicConstraintStorage<Sos1ConstraintData> sos1_constraints_;
683 AtomicConstraintStorage<Sos2ConstraintData> sos2_constraints_;
684 AtomicConstraintStorage<IndicatorConstraintData> indicator_constraints_;
686 UpdateTrackers<UpdateTrackerData> update_trackers_;
700 return AddVariable(-std::numeric_limits<double>::infinity(),
701 std::numeric_limits<double>::infinity(),
false,
name);
717 return variables_.
name(
id);
731 const bool is_integer) {
732 variables_.
set_integer(
id, is_integer, UpdateAndGetVariableDiffs());
763 std::numeric_limits<double>::infinity(),
name);
767 const LinearConstraintId
id)
const {
772 const LinearConstraintId
id)
const {
777 const LinearConstraintId
id)
const {
778 return linear_constraints_.
name(
id);
782 const LinearConstraintId
id,
const double lower_bound) {
784 UpdateAndGetLinearConstraintDiffs());
788 const LinearConstraintId
id,
const double upper_bound) {
790 UpdateAndGetLinearConstraintDiffs());
794 return linear_constraints_.
size();
798 return linear_constraints_.
next_id();
802 LinearConstraintId
id) {
807 return linear_constraints_.
contains(
id);
815 LinearConstraintId constraint, VariableId variable)
const {
816 return linear_constraints_.
matrix().
get(constraint, variable);
820 LinearConstraintId constraint, VariableId variable)
const {
821 return linear_constraints_.
matrix().
contains(constraint, variable);
825 const LinearConstraintId constraint,
const VariableId variable,
826 const double value) {
828 UpdateAndGetLinearConstraintDiffs());
831 std::vector<std::tuple<LinearConstraintId, VariableId, double>>
837 LinearConstraintId constraint)
const {
838 return linear_constraints_.
matrix().
row(constraint);
842 VariableId variable)
const {
855 const VariableId variable)
const {
860 const VariableId first_variable,
const VariableId second_variable)
const {
861 return objective_.
quadratic_term(first_variable, second_variable);
865 const VariableId variable)
const {
870 const VariableId first_variable,
const VariableId second_variable)
const {
888 const double value) {
893 const VariableId first_variable,
const VariableId second_variable,
894 const double value) {
896 UpdateAndGetObjectiveDiffs());
900 objective_.
Clear(UpdateAndGetObjectiveDiffs());
912 std::vector<std::tuple<VariableId, VariableId, double>>
921 template <
typename Constra
intData>
923 ConstraintData data) {
924 return constraint_storage<ConstraintData>().AddConstraint(data);
927 template <
typename IdType>
929 using ConstraintData =
931 auto& storage = constraint_storage<ConstraintData>();
932 CHECK(storage.contains(
id));
936 UpdateTrackerData::AtomicConstraintDirtyFieldPtr<ConstraintData>()>(
940 template <
typename IdType>
943 using ConstraintData =
945 return constraint_storage<ConstraintData>().data(
id);
948 template <
typename IdType>
950 using ConstraintData =
952 return constraint_storage<ConstraintData>().size();
955 template <
typename IdType>
957 using ConstraintData =
959 return constraint_storage<ConstraintData>().next_id();
962 template <
typename IdType>
964 using ConstraintData =
966 return constraint_storage<ConstraintData>().ensure_next_id_at_least(
id);
969 template <
typename IdType>
971 using ConstraintData =
973 return constraint_storage<ConstraintData>().contains(
id);
976 template <
typename IdType>
978 using ConstraintData =
980 return constraint_storage<ConstraintData>().Constraints();
983 template <
typename IdType>
985 using ConstraintData =
987 return constraint_storage<ConstraintData>().SortedConstraints();
990 template <
typename IdType>
992 const VariableId variable_id)
const {
993 using ConstraintData =
995 const absl::flat_hash_set<IdType> constraints =
996 constraint_storage<ConstraintData>().RelatedConstraints(variable_id);
997 return {constraints.begin(), constraints.end()};
1000 template <
typename IdType>
1002 const IdType
id)
const {
1014 ModelStorage::constraint_storage() {
1015 return quadratic_constraints_;
1020 ModelStorage::constraint_storage()
const {
1021 return quadratic_constraints_;
1026 ModelStorage::UpdateTrackerData::*
1027 ModelStorage::UpdateTrackerData::AtomicConstraintDirtyFieldPtr<
1029 return &UpdateTrackerData::dirty_quadratic_constraints;
1035 inline AtomicConstraintStorage<Sos1ConstraintData>&
1036 ModelStorage::constraint_storage() {
1037 return sos1_constraints_;
1041 inline const AtomicConstraintStorage<Sos1ConstraintData>&
1042 ModelStorage::constraint_storage()
const {
1043 return sos1_constraints_;
1047 constexpr
typename AtomicConstraintStorage<Sos1ConstraintData>::Diff
1048 ModelStorage::UpdateTrackerData::*
1049 ModelStorage::UpdateTrackerData::AtomicConstraintDirtyFieldPtr<
1051 return &UpdateTrackerData::dirty_sos1_constraints;
1057 inline AtomicConstraintStorage<Sos2ConstraintData>&
1058 ModelStorage::constraint_storage() {
1059 return sos2_constraints_;
1063 inline const AtomicConstraintStorage<Sos2ConstraintData>&
1064 ModelStorage::constraint_storage()
const {
1065 return sos2_constraints_;
1069 constexpr
typename AtomicConstraintStorage<Sos2ConstraintData>::Diff
1070 ModelStorage::UpdateTrackerData::*
1071 ModelStorage::UpdateTrackerData::AtomicConstraintDirtyFieldPtr<
1073 return &UpdateTrackerData::dirty_sos2_constraints;
1079 inline AtomicConstraintStorage<IndicatorConstraintData>&
1080 ModelStorage::constraint_storage() {
1081 return indicator_constraints_;
1085 inline const AtomicConstraintStorage<IndicatorConstraintData>&
1086 ModelStorage::constraint_storage()
const {
1087 return indicator_constraints_;
1091 constexpr
typename AtomicConstraintStorage<IndicatorConstraintData>::Diff
1092 ModelStorage::UpdateTrackerData::*
1093 ModelStorage::UpdateTrackerData::AtomicConstraintDirtyFieldPtr<
1094 IndicatorConstraintData>() {
1095 return &UpdateTrackerData::dirty_indicator_constraints;
double lower_bound(LinearConstraintId id) const
void set_upper_bound(LinearConstraintId id, double upper_bound, const iterator_range< DiffIter > &diffs)
double upper_bound(LinearConstraintId id) const
const SparseMatrix< LinearConstraintId, VariableId > & matrix() const
void set_lower_bound(LinearConstraintId id, double lower_bound, const iterator_range< DiffIter > &diffs)
LinearConstraintId next_id() const
bool contains(LinearConstraintId id) const
const std::string & name(LinearConstraintId id) const
void set_term(LinearConstraintId constraint, VariableId variable, double value, const iterator_range< DiffIter > &diffs)
void ensure_next_id_at_least(LinearConstraintId minimum)
LinearConstraintId next_linear_constraint_id() const
void set_quadratic_objective_coefficient(VariableId first_variable, VariableId second_variable, double value)
std::vector< VariableId > SortedVariables() const
void DeleteVariable(VariableId id)
std::vector< LinearConstraintId > linear_constraints_with_variable(VariableId variable) const
ModelStorage & operator=(const ModelStorage &)=delete
void set_variable_as_continuous(VariableId id)
double linear_objective_coefficient(VariableId variable) const
int num_linear_constraints() const
static absl::StatusOr< std::unique_ptr< ModelStorage > > FromModelProto(const ModelProto &model_proto)
IdType next_constraint_id() const
double linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable) const
std::optional< ModelUpdateProto > ExportModelUpdate(UpdateTrackerId update_tracker) const
void DeleteLinearConstraint(LinearConstraintId id)
void set_linear_objective_coefficient(VariableId variable, double value)
int64_t num_quadratic_objective_terms() const
const AtomicConstraintTraits< IdType >::ConstraintData & constraint_data(IdType id) const
void DeleteUpdateTracker(UpdateTrackerId update_tracker)
std::vector< VariableId > variables() const
ConstraintData::IdType AddAtomicConstraint(ConstraintData data)
int num_variables() const
double linear_constraint_lower_bound(LinearConstraintId id) const
bool is_quadratic_objective_coefficient_nonzero(VariableId first_variable, VariableId second_variable) const
double objective_offset() const
ModelStorage(absl::string_view name="")
absl::Status ApplyUpdateProto(const ModelUpdateProto &update_proto)
void set_linear_constraint_coefficient(LinearConstraintId constraint, VariableId variable, double value)
VariableId AddVariable(absl::string_view name="")
void AdvanceCheckpoint(UpdateTrackerId update_tracker)
void set_variable_upper_bound(VariableId id, double upper_bound)
std::vector< VariableId > variables_in_linear_constraint(LinearConstraintId constraint) const
void set_variable_is_integer(VariableId id, bool is_integer)
void ensure_next_variable_id_at_least(VariableId id)
bool has_linear_constraint(LinearConstraintId id) const
const std::string & variable_name(VariableId id) const
std::vector< IdType > Constraints() const
void set_linear_constraint_upper_bound(LinearConstraintId id, double upper_bound)
ModelProto ExportModel() const
UpdateTrackerId NewUpdateTracker()
void set_is_maximize(bool is_maximize)
double quadratic_objective_coefficient(VariableId first_variable, VariableId second_variable) const
void set_linear_constraint_lower_bound(LinearConstraintId id, double lower_bound)
VariableId next_variable_id() const
double linear_constraint_upper_bound(LinearConstraintId id) const
std::vector< LinearConstraintId > LinearConstraints() const
void set_variable_as_integer(VariableId id)
std::vector< std::tuple< VariableId, VariableId, double > > quadratic_objective_terms() const
bool has_constraint(IdType id) const
std::unique_ptr< ModelStorage > Clone(std::optional< absl::string_view > new_name=std::nullopt) const
int64_t num_constraints() const
std::vector< std::tuple< LinearConstraintId, VariableId, double > > linear_constraint_matrix() const
bool has_variable(VariableId id) const
void ensure_next_constraint_id_at_least(IdType id)
ModelStorage(const ModelStorage &)=delete
double variable_lower_bound(VariableId id) const
const std::string & name() const
void ensure_next_linear_constraint_id_at_least(LinearConstraintId id)
void DeleteAtomicConstraint(IdType id)
bool is_linear_constraint_coefficient_nonzero(LinearConstraintId constraint, VariableId variable) const
bool is_variable_integer(VariableId id) const
const std::string & linear_constraint_name(LinearConstraintId id) const
std::vector< IdType > ConstraintsWithVariable(VariableId variable_id) const
LinearConstraintId AddLinearConstraint(absl::string_view name="")
const absl::flat_hash_map< VariableId, double > & linear_objective() const
std::vector< LinearConstraintId > SortedLinearConstraints() const
bool is_linear_objective_coefficient_nonzero(VariableId variable) const
std::vector< IdType > SortedConstraints() const
double variable_upper_bound(VariableId id) const
void set_variable_lower_bound(VariableId id, double lower_bound)
std::vector< VariableId > VariablesInConstraint(IdType id) const
void set_objective_offset(double value)
const absl::flat_hash_map< VariableId, double > & linear_terms() const
double linear_term(VariableId v) const
void Clear(const iterator_range< DiffIter > &diffs)
double quadratic_term(const VariableId v1, const VariableId v2) const
void set_maximize(bool maximize, const iterator_range< DiffIter > &diffs)
void set_offset(double offset, const iterator_range< DiffIter > &diffs)
void set_linear_term(VariableId variable, double value, const iterator_range< DiffIter > &diffs)
void set_quadratic_term(VariableId v1, VariableId v2, double val, const iterator_range< DiffIter > &diffs)
const SparseSymmetricMatrix & quadratic_terms() const
std::vector< RowId > column(ColumnId column_id) const
std::vector< std::tuple< RowId, ColumnId, double > > Terms() const
bool contains(RowId row, ColumnId column) const
std::vector< ColumnId > row(RowId row_id) const
double get(RowId row, ColumnId column) const
double get(VariableId first, VariableId second) const
std::vector< std::pair< VariableId, double > > Terms(VariableId variable) const
const std::vector< IdDataPair > & GetUpdatedTrackers()
void set_integer(VariableId id, bool is_integer, const iterator_range< DiffIter > &diffs)
void set_lower_bound(VariableId id, double lower_bound, const iterator_range< DiffIter > &diffs)
void set_upper_bound(VariableId id, double upper_bound, const iterator_range< DiffIter > &diffs)
double upper_bound(VariableId id) const
const std::string & name(VariableId id) const
double lower_bound(VariableId id) const
VariableId next_id() const
void ensure_next_id_at_least(VariableId minimum)
bool is_integer(VariableId id) const
bool contains(VariableId id) const
CpModelProto const * model_proto
absl::Span< const double > coefficients
internal::SosConstraintData< Sos1ConstraintId > Sos1ConstraintData
internal::SosConstraintData< Sos2ConstraintId > Sos2ConstraintData
auto MakeUpdateDataFieldRange(const UpdateTrackers &trackers)
Collection of objects used to extend the Constraint Solver library.