14#ifndef OR_TOOLS_MATH_OPT_STORAGE_OBJECTIVE_STORAGE_H_
15#define OR_TOOLS_MATH_OPT_STORAGE_OBJECTIVE_STORAGE_H_
24#include "absl/container/flat_hash_map.h"
25#include "absl/container/flat_hash_set.h"
26#include "absl/types/span.h"
27#include "google/protobuf/map.h"
29#include "ortools/math_opt/model.pb.h"
30#include "ortools/math_opt/model_update.pb.h"
46 inline bool empty()
const;
65 absl::flat_hash_set<std::pair<VariableId, VariableId>>
83 absl::flat_hash_set<AuxiliaryObjectiveId>
deleted;
94 absl::string_view
name);
101 VariableId v2)
const;
103 inline const absl::flat_hash_map<VariableId, double>&
linear_terms(
107 template <
typename DiffIter>
111 template <
typename DiffIter>
115 template <
typename DiffIter>
119 template <
typename DiffIter>
123 template <
typename DiffIter>
131 template <
typename DiffIter>
143 inline AuxiliaryObjectiveId
next_id()
const;
150 inline bool contains(AuxiliaryObjectiveId
id)
const;
164 template <
typename DiffIter>
169 template <
typename DiffIter>
175 std::pair<ObjectiveProto, google::protobuf::Map<int64_t, ObjectiveProto>>
192 std::pair<ObjectiveUpdatesProto, AuxiliaryObjectivesUpdatesProto>
Update(
194 const absl::flat_hash_set<VariableId>& deleted_variables,
195 absl::Span<const VariableId> new_variables)
const;
202 struct ObjectiveData {
203 ObjectiveProto Proto()
const;
206 std::optional<ObjectiveUpdatesProto> Update(
207 const Diff::SingleObjective& diff_data,
208 const absl::flat_hash_set<VariableId>& deleted_variables,
209 absl::Span<const VariableId> new_variables)
const;
211 inline void DeleteVariable(VariableId variable);
213 bool maximize =
false;
214 int64_t priority = 0;
218 std::string name =
"";
221 inline const ObjectiveData& objective(
ObjectiveId id)
const;
224 AuxiliaryObjectiveId next_id_{0};
225 ObjectiveData primary_objective_;
226 absl::flat_hash_map<AuxiliaryObjectiveId, ObjectiveData>
227 auxiliary_objectives_;
245 primary_objective_.name = std::string(
name);
249 return objective(
id).maximize;
253 return objective(
id).priority;
257 return objective(
id).offset;
261 const VariableId v)
const {
262 return objective(
id).linear_terms.get(v);
267 const VariableId v2)
const {
268 return objective(
id).quadratic_terms.get(v1, v2);
272 return objective(
id).name;
277 return objective(
id).linear_terms.terms();
282 return objective(
id).quadratic_terms;
285template <
typename DiffIter>
292 for (
Diff& diff : diffs) {
293 if (diff.objective_tracked(
id)) {
294 diff.objective_diffs[id].direction =
true;
299template <
typename DiffIter>
302 const iterator_range<DiffIter>& diffs) {
307 for (
Diff& diff : diffs) {
308 if (diff.objective_tracked(
id)) {
309 diff.objective_diffs[id].priority =
true;
314template <
typename DiffIter>
316 const iterator_range<DiffIter>& diffs) {
320 objective(
id).offset =
offset;
321 for (
Diff& diff : diffs) {
322 if (diff.objective_tracked(
id)) {
323 diff.objective_diffs[id].offset =
true;
328template <
typename DiffIter>
330 const VariableId variable,
332 const iterator_range<DiffIter>& diffs) {
334 for (
Diff& diff : diffs) {
335 if (diff.objective_tracked(
id) && variable < diff.variable_checkpoint) {
336 diff.objective_diffs[id].linear_coefficients.insert(variable);
342template <
typename DiffIter>
344 const ObjectiveId id,
const VariableId v1,
const VariableId v2,
345 const double val,
const iterator_range<DiffIter>& diffs) {
348 if (diff.objective_tracked(
id) && v1 < diff.variable_checkpoint &&
349 v2 < diff.variable_checkpoint) {
350 diff.objective_diffs[id].quadratic_coefficients.insert(
351 {std::min(v1, v2), std::max(v1, v2)});
357template <
typename DiffIter>
359 const iterator_range<DiffIter>& diffs) {
360 CHECK(auxiliary_objectives_.contains(
id));
361 for (
Diff& diff : diffs) {
362 if (diff.objective_tracked(
id)) {
363 diff.deleted.insert(
id);
364 diff.objective_diffs.erase(
id);
367 auxiliary_objectives_.erase(
id);
371 return auxiliary_objectives_.size();
379 const AuxiliaryObjectiveId minimum) {
380 next_id_ = std::max(minimum, next_id_);
384 return auxiliary_objectives_.contains(
id);
387template <
typename DiffIter>
390 ObjectiveData& data = objective(
id);
393 if (!diff.objective_tracked(
id)) {
396 for (
const auto& [
var, _] : data.linear_terms.terms()) {
397 if (
var < diff.variable_checkpoint) {
398 diff.objective_diffs[id].linear_coefficients.insert(
var);
401 for (
const auto& [v1, v2, _] : data.quadratic_terms.Terms()) {
402 if (v2 < diff.variable_checkpoint) {
403 diff.objective_diffs[id].quadratic_coefficients.insert({v1, v2});
407 data.linear_terms.clear();
408 data.quadratic_terms.Clear();
411template <
typename DiffIter>
413 const iterator_range<DiffIter>& diffs) {
414 for (
Diff& diff : diffs) {
415 for (
auto& [
id, obj_diff_data] : diff.objective_diffs) {
416 obj_diff_data.DeleteVariable(variable, diff.variable_checkpoint,
420 primary_objective_.DeleteVariable(variable);
421 for (
auto& [unused, aux_obj] : auxiliary_objectives_) {
422 aux_obj.DeleteVariable(variable);
427 if (next_id_ > diff.objective_checkpoint) {
431 for (
const auto& [unused, diff_data] : diff.objective_diffs) {
432 if (!diff_data.empty()) {
438 return diff.deleted.empty();
449const ObjectiveStorage::ObjectiveData& ObjectiveStorage::objective(
452 return primary_objective_;
454 const auto it = auxiliary_objectives_.find(*
id);
455 CHECK(it != auxiliary_objectives_.end());
459ObjectiveStorage::ObjectiveData& ObjectiveStorage::objective(
ObjectiveId id) {
461 return primary_objective_;
463 const auto it = auxiliary_objectives_.find(*
id);
464 CHECK(it != auxiliary_objectives_.end());
468void ObjectiveStorage::ObjectiveData::DeleteVariable(VariableId variable) {
In memory representation of the objective of an optimization model.
void set_linear_term(ObjectiveId id, VariableId variable, double value, const iterator_range< DiffIter > &diffs)
double offset(ObjectiveId id) const
bool contains(AuxiliaryObjectiveId id) const
Returns true if this id has been created and not yet deleted.
const SparseSymmetricMatrix & quadratic_terms(ObjectiveId id) const
void Clear(ObjectiveId id, const iterator_range< DiffIter > &diffs)
std::pair< ObjectiveProto, google::protobuf::Map< int64_t, ObjectiveProto > > Proto() const
std::vector< AuxiliaryObjectiveId > SortedAuxiliaryObjectives() const
void set_priority(ObjectiveId id, int64_t priority, const iterator_range< DiffIter > &diffs)
const absl::flat_hash_map< VariableId, double > & linear_terms(ObjectiveId id) const
bool maximize(ObjectiveId id) const
AuxiliaryObjectiveId next_id() const
const std::string & name(ObjectiveId id) const
void set_offset(ObjectiveId id, double offset, const iterator_range< DiffIter > &diffs)
ObjectiveStorage(absl::string_view name={})
void AdvanceCheckpointInDiff(VariableId variable_checkpoint, Diff &diff) const
Updates the checkpoint and clears all stored changes in diff.
void Delete(AuxiliaryObjectiveId id, const iterator_range< DiffIter > &diffs)
int64_t num_auxiliary_objectives() const
std::vector< AuxiliaryObjectiveId > AuxiliaryObjectives() const
The AuxiliaryObjectivesIds in use (not deleted), order not defined.
int64_t priority(ObjectiveId id) const
AuxiliaryObjectiveId AddAuxiliaryObjective(int64_t priority, absl::string_view name)
double linear_term(ObjectiveId id, VariableId v) const
void set_maximize(ObjectiveId id, bool maximize, const iterator_range< DiffIter > &diffs)
void DeleteVariable(VariableId variable, const iterator_range< DiffIter > &diffs)
void ensure_next_id_at_least(AuxiliaryObjectiveId minimum)
double quadratic_term(ObjectiveId id, VariableId v1, VariableId v2) const
std::pair< ObjectiveUpdatesProto, AuxiliaryObjectivesUpdatesProto > Update(const Diff &diff, const absl::flat_hash_set< VariableId > &deleted_variables, absl::Span< const VariableId > new_variables) const
bool diff_is_empty(const Diff &diff) const
void set_quadratic_term(ObjectiveId id, VariableId v1, VariableId v2, double val, const iterator_range< DiffIter > &diffs)
void Delete(VariableId variable)
Zeros out all coefficients for this variable.
bool set(VariableId first, VariableId second, double value)
const std::string name
A name for logging purposes.
An object oriented wrapper for quadratic constraints in ModelStorage.
constexpr ObjectiveId kPrimaryObjectiveId
std::optional< AuxiliaryObjectiveId > ObjectiveId
nullopt denotes the primary objective.
absl::flat_hash_set< std::pair< VariableId, VariableId > > quadratic_coefficients
void DeleteVariable(VariableId deleted_variable, VariableId variable_checkpoint, const SparseSymmetricMatrix &quadratic_terms)
absl::flat_hash_set< VariableId > linear_coefficients
bool objective_tracked(ObjectiveId id) const
absl::flat_hash_map< ObjectiveId, SingleObjective > objective_diffs
Diff(const ObjectiveStorage &storage, VariableId variable_checkpoint)
absl::flat_hash_set< AuxiliaryObjectiveId > deleted
VariableId variable_checkpoint
AuxiliaryObjectiveId objective_checkpoint