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);