33 : num_tasks_(helper->NumTasks()),
37 integer_trail_(integer_trail) {
39 mandatory_energy_before_end_max_.resize(num_tasks_);
40 mandatory_energy_before_start_min_.resize(num_tasks_);
43 size_free_.resize(num_tasks_);
44 energy_free_.resize(num_tasks_);
48 const int id = watcher->
Register(
this);
51 for (
int t = 0; t < num_tasks_; t++) {
61 if (!TimeTableEdgeFindingPass())
return false;
64 if (!TimeTableEdgeFindingPass())
return false;
67 if (old_timestamp == integer_trail_->
num_enqueues())
break;
72 void TimeTableEdgeFinding::BuildTimeTable() {
77 for (
const auto task_time :
79 const int t = task_time.task_index;
81 if (task_time.time < helper_->
EndMin(t)) {
82 scp_.push_back(task_time);
88 const int t = task_time.task_index;
90 if (helper_->
StartMax(t) < task_time.time) {
91 ecp_.push_back(task_time);
97 const std::vector<TaskTime>& by_decreasing_end_max =
99 const std::vector<TaskTime>& by_start_min =
102 IntegerValue height = IntegerValue(0);
103 IntegerValue
energy = IntegerValue(0);
107 IntegerValue previous_time = IntegerValue(0);
112 int index_emax = num_tasks_ - 1;
114 while (index_emax >= 0) {
117 IntegerValue
time = by_decreasing_end_max[index_emax].time;
118 if (index_smin < num_tasks_) {
121 if (index_scp < scp_.size()) {
124 if (index_ecp < ecp_.size()) {
130 previous_time =
time;
133 while (index_smin < num_tasks_ && by_start_min[index_smin].
time ==
time) {
134 mandatory_energy_before_start_min_[by_start_min[index_smin].task_index] =
140 while (index_emax >= 0 && by_decreasing_end_max[index_emax].
time ==
time) {
141 mandatory_energy_before_end_max_[by_decreasing_end_max[index_emax]
147 while (index_scp < scp_.size() && scp_[index_scp].time ==
time) {
148 height += DemandMin(scp_[index_scp].task_index);
153 while (index_ecp < ecp_.size() && ecp_[index_ecp].time ==
time) {
154 height -= DemandMin(ecp_[index_ecp].task_index);
160 bool TimeTableEdgeFinding::TimeTableEdgeFindingPass() {
163 for (
int t = 0; t < num_tasks_; ++t) {
168 size_free_[t] = helper_->
SizeMin(t);
172 energy_free_[t] = size_free_[t] * DemandMin(t);
184 const int end_task = end_task_time.task_index;
187 if (!helper_->
IsPresent(end_task))
continue;
188 if (energy_free_[end_task] == 0)
continue;
191 if (end_task_time.time == previous_end)
continue;
192 previous_end = end_task_time.time;
195 IntegerValue energy_free_parts = IntegerValue(0);
200 IntegerValue free_energy_of_max_task_in_window(0);
205 const int begin_task = begin_task_time.task_index;
208 if (!helper_->
IsPresent(begin_task))
continue;
209 if (energy_free_[begin_task] == 0)
continue;
213 const IntegerValue begin = begin_task_time.time;
214 const IntegerValue end = end_task_time.time;
217 if (end <= begin)
continue;
238 energy_free_parts += energy_free_[begin_task];
240 const IntegerValue demand_min = DemandMin(begin_task);
241 const IntegerValue extra_energy =
242 std::min(size_free_[begin_task], (end - begin)) * demand_min;
246 const IntegerValue free_energy_in_window =
248 size_free_[begin_task] - (
end_max - end)) *
251 if (extra_energy > extra_energy_required_by_max_task) {
252 max_task = begin_task;
253 extra_energy_required_by_max_task = extra_energy;
257 energy_free_parts += free_energy_of_max_task_in_window;
258 free_energy_of_max_task_in_window = free_energy_in_window;
260 energy_free_parts += free_energy_in_window;
268 if (max_task == -1)
continue;
271 const IntegerValue interval_energy = CapacityMax() * (end - begin);
272 const IntegerValue energy_mandatory =
273 mandatory_energy_before_end_max_[end_task] -
274 mandatory_energy_before_start_min_[begin_task];
275 const IntegerValue available_energy =
276 interval_energy - energy_free_parts - energy_mandatory;
279 if (extra_energy_required_by_max_task <= available_energy)
continue;
287 const IntegerValue mandatory_in =
std::max(
292 const IntegerValue new_start =
293 end - mandatory_in - (available_energy / DemandMin(max_task));
296 if (helper_->
StartMin(max_task) < new_start) {
297 if (!IncreaseStartMin(begin, end, max_task, new_start))
return false;
305 bool TimeTableEdgeFinding::IncreaseStartMin(IntegerValue begin,
306 IntegerValue end,
int task_index,
307 IntegerValue new_start) {
313 mutable_reason->push_back(
320 mutable_reason->push_back(
327 for (
int t = 0; t < num_tasks_; ++t) {
328 if (t == task_index)
continue;
330 if (helper_->
EndMax(t) <= begin)
continue;
331 if (helper_->
StartMin(t) >= end)
continue;
334 mutable_reason->push_back(