35 std::move(energies),
capacity, integer_trail, helper);
36 constraint->RegisterWith(watcher);
37 model->TakeOwnership(constraint);
47 std::vector<AffineExpression> energies;
48 const int num_tasks = helper->
NumTasks();
50 for (
int t = 0; t < num_tasks; ++t) {
60 energies.push_back(size);
61 energies.back().coeff *=
demand.constant;
62 energies.back().constant *=
demand.constant;
65 energies.push_back(
demand);
66 energies.back().coeff *= size.
constant;
67 energies.back().constant *= size.
constant;
74 LOG(
INFO) <<
"Overload checker with variable demand and variable size "
75 "is currently not implemented. Skipping.";
83 model->TakeOwnership(constraint);
89 : energies_(std::move(energies)),
91 integer_trail_(integer_trail),
94 const int num_tasks = helper_->
NumTasks();
95 CHECK_EQ(energies_.size(), num_tasks);
96 task_to_start_event_.resize(num_tasks);
100 const int id = watcher->
Register(
this);
110 const IntegerValue capacity_max = integer_trail_->
UpperBound(capacity_);
112 if (capacity_max <= 0)
return true;
115 start_event_task_time_.clear();
118 const int task = task_time.task_index;
120 integer_trail_->
UpperBound(energies_[task]) == 0) {
121 task_to_start_event_[task] = -1;
124 start_event_task_time_.emplace_back(task_time);
125 task_to_start_event_[task] = num_events;
128 start_event_is_present_.assign(num_events,
false);
129 theta_tree_.
Reset(num_events);
131 bool tree_has_mandatory_intervals =
false;
134 for (
const auto task_time :
136 const int current_task = task_time.task_index;
137 const IntegerValue current_end = task_time.time;
138 if (task_to_start_event_[current_task] == -1)
continue;
142 const int current_event = task_to_start_event_[current_task];
143 const IntegerValue
start_min = start_event_task_time_[current_event].time;
144 const bool is_present = helper_->
IsPresent(current_task);
145 start_event_is_present_[current_event] = is_present;
147 tree_has_mandatory_intervals =
true;
150 integer_trail_->
LowerBound(energies_[current_task]),
151 integer_trail_->
UpperBound(energies_[current_task]));
155 integer_trail_->
UpperBound(energies_[current_task]));
159 if (tree_has_mandatory_intervals) {
161 const IntegerValue envelope = theta_tree_.
GetEnvelope();
162 const int critical_event =
164 const IntegerValue window_start =
165 start_event_task_time_[critical_event].time;
166 const IntegerValue window_end = current_end;
167 const IntegerValue window_size = window_end - window_start;
168 if (window_size == 0)
continue;
169 const IntegerValue new_capacity_min =
170 CeilRatio(envelope - window_start * capacity_max, window_size);
178 if (new_capacity_min > integer_trail_->
LowerBound(capacity_)) {
180 for (
int event = critical_event;
event < num_events;
event++) {
181 if (start_event_is_present_[event]) {
182 const int task = start_event_task_time_[event].task_index;
217 int event_with_new_energy_max;
218 IntegerValue new_energy_max;
220 current_end * capacity_max, &critical_event,
221 &event_with_new_energy_max, &new_energy_max);
223 const IntegerValue window_start =
224 start_event_task_time_[critical_event].time;
227 const IntegerValue window_end = current_end;
228 for (
int event = critical_event;
event < num_events;
event++) {
229 if (start_event_is_present_[event]) {
230 if (event == event_with_new_energy_max)
continue;
231 const int task = start_event_task_time_[event].task_index;
246 const int task_with_new_energy_max =
247 start_event_task_time_[event_with_new_energy_max].task_index;
252 integer_trail_->
LowerBound(energies_[task_with_new_energy_max])) {
253 if (helper_->
IsOptional(task_with_new_energy_max)) {
260 energies_[task_with_new_energy_max].LowerOrEqual(new_energy_max);
267 if (helper_->
IsPresent(task_with_new_energy_max)) {
269 task_to_start_event_[task_with_new_energy_max],
270 start_event_task_time_[event_with_new_energy_max].
time *
272 integer_trail_->
LowerBound(energies_[task_with_new_energy_max]),
275 theta_tree_.
RemoveEvent(event_with_new_energy_max);
#define CHECK_EQ(val1, val2)
#define CHECK_GE(val1, val2)
void RegisterWith(GenericLiteralWatcher *watcher)
CumulativeEnergyConstraint(std::vector< AffineExpression > energies, AffineExpression capacity, IntegerTrail *integer_trail, SchedulingConstraintHelper *helper)
int Register(PropagatorInterface *propagator)
void NotifyThatPropagatorMayNotReachFixedPointInOnePass(int id)
IntegerLiteral LowerBoundAsLiteral(IntegerVariable i) const
IntegerValue UpperBound(IntegerVariable i) const
IntegerValue LowerBound(IntegerVariable i) const
IntegerLiteral UpperBoundAsLiteral(IntegerVariable i) const
Class that owns everything related to a particular optimization model.
ABSL_MUST_USE_RESULT bool PushIntegerLiteral(IntegerLiteral lit)
const std::vector< TaskTime > & TaskByDecreasingEndMax()
ABSL_MUST_USE_RESULT bool PushTaskAbsence(int t)
const std::vector< TaskTime > & TaskByIncreasingStartMin()
void AddStartMinReason(int t, IntegerValue lower_bound)
void WatchAllTasks(int id, GenericLiteralWatcher *watcher, bool watch_start_max=true, bool watch_end_max=true) const
void AddPresenceReason(int t)
std::vector< IntegerLiteral > * MutableIntegerReason()
bool IsPresent(int t) const
ABSL_MUST_USE_RESULT bool PushIntegerLiteralIfTaskPresent(int t, IntegerLiteral lit)
void SynchronizeAndSetTimeDirection(bool is_forward)
bool IsAbsent(int t) const
ABSL_MUST_USE_RESULT bool ReportConflict()
bool IsOptional(int t) const
void AddEndMaxReason(int t, IntegerValue upper_bound)
const std::vector< AffineExpression > & Sizes() const
void GetEventsWithOptionalEnvelopeGreaterThan(IntegerType target_envelope, int *critical_event, int *optional_event, IntegerType *available_energy) const
IntegerType GetOptionalEnvelope() const
void RemoveEvent(int event)
int GetMaxEventWithEnvelopeGreaterThan(IntegerType target_envelope) const
void Reset(int num_events)
void AddOrUpdateOptionalEvent(int event, IntegerType initial_envelope_opt, IntegerType energy_max)
void AddOrUpdateEvent(int event, IntegerType initial_envelope, IntegerType energy_min, IntegerType energy_max)
IntegerType GetEnvelope() const
ReverseView< Container > reversed_view(const Container &c)
void AddCumulativeOverloadChecker(const std::vector< AffineExpression > &demands, AffineExpression capacity, SchedulingConstraintHelper *helper, Model *model)
IntegerValue CeilRatio(IntegerValue dividend, IntegerValue positive_divisor)
const IntegerVariable kNoIntegerVariable(-1)
void AddCumulativeEnergyConstraint(std::vector< AffineExpression > energies, AffineExpression capacity, SchedulingConstraintHelper *helper, Model *model)
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
IntegerLiteral GreaterOrEqual(IntegerValue bound) const