26 IntegerValue fixed_size,
27 LiteralIndex is_present) {
29 const IntervalVariable i(start_vars_.
size());
36 std::vector<Literal> enforcement_literals;
38 enforcement_literals.push_back(
Literal(is_present));
43 SizeVar(i), enforcement_literals);
48 enforcement_literals);
53 const std::vector<IntervalVariable>& tasks,
Model*
model)
60 minus_end_vars_.clear();
61 minus_start_vars_.clear();
62 duration_vars_.clear();
63 fixed_durations_.clear();
64 reason_for_presence_.clear();
65 for (
const IntervalVariable i : tasks) {
66 if (repository->IsOptional(i)) {
67 reason_for_presence_.push_back(repository->IsPresentLiteral(i).Index());
73 fixed_durations_.push_back(repository->MinSize(i));
75 duration_vars_.push_back(repository->SizeVar(i));
76 fixed_durations_.push_back(IntegerValue(0));
78 start_vars_.push_back(repository->StartVar(i));
79 end_vars_.push_back(repository->EndVar(i));
80 minus_start_vars_.push_back(
NegationOf(repository->StartVar(i)));
81 minus_end_vars_.push_back(
NegationOf(repository->EndVar(i)));
92 start_vars_.resize(num_tasks);
98 current_time_direction_ = other.current_time_direction_;
100 const int num_tasks = tasks.size();
101 start_vars_.resize(num_tasks);
102 end_vars_.resize(num_tasks);
103 minus_end_vars_.resize(num_tasks);
104 minus_start_vars_.resize(num_tasks);
105 duration_vars_.resize(num_tasks);
106 fixed_durations_.resize(num_tasks);
107 reason_for_presence_.resize(num_tasks);
108 for (
int i = 0; i < num_tasks; ++i) {
109 const int t = tasks[i];
110 start_vars_[i] = other.start_vars_[t];
111 end_vars_[i] = other.end_vars_[t];
112 minus_end_vars_[i] = other.minus_end_vars_[t];
113 minus_start_vars_[i] = other.minus_start_vars_[t];
114 duration_vars_[i] = other.duration_vars_[t];
115 fixed_durations_[i] = other.fixed_durations_[t];
116 reason_for_presence_[i] = other.reason_for_presence_[t];
122 void SchedulingConstraintHelper::InitSortedVectors() {
123 const int num_tasks = start_vars_.size();
124 task_by_increasing_start_min_.resize(num_tasks);
125 task_by_increasing_end_min_.resize(num_tasks);
126 task_by_decreasing_start_max_.resize(num_tasks);
127 task_by_decreasing_end_max_.resize(num_tasks);
128 task_by_increasing_shifted_start_min_.resize(num_tasks);
129 task_by_negated_shifted_end_max_.resize(num_tasks);
130 for (
int t = 0; t < num_tasks; ++t) {
131 task_by_increasing_start_min_[t].task_index = t;
132 task_by_increasing_end_min_[t].task_index = t;
133 task_by_decreasing_start_max_[t].task_index = t;
134 task_by_decreasing_end_max_[t].task_index = t;
135 task_by_increasing_shifted_start_min_[t].task_index = t;
136 task_by_negated_shifted_end_max_[t].task_index = t;
138 shifted_start_min_timestamp_ = -1;
139 negated_shifted_end_max_timestamp_ = -1;
143 if (current_time_direction_ == is_forward)
return;
144 current_time_direction_ = is_forward;
146 std::swap(start_vars_, minus_end_vars_);
147 std::swap(end_vars_, minus_start_vars_);
148 std::swap(task_by_increasing_start_min_, task_by_decreasing_end_max_);
149 std::swap(task_by_increasing_end_min_, task_by_decreasing_start_max_);
150 std::swap(task_by_increasing_shifted_start_min_,
151 task_by_negated_shifted_end_max_);
152 std::swap(shifted_start_min_timestamp_, negated_shifted_end_max_timestamp_);
155 const std::vector<TaskTime>&
158 for (
int i = 0; i < num_tasks; ++i) {
159 TaskTime& ref = task_by_increasing_start_min_[i];
163 task_by_increasing_start_min_.end());
164 return task_by_increasing_start_min_;
167 const std::vector<TaskTime>&
170 for (
int i = 0; i < num_tasks; ++i) {
171 TaskTime& ref = task_by_increasing_end_min_[i];
175 task_by_increasing_end_min_.end());
176 return task_by_increasing_end_min_;
179 const std::vector<TaskTime>&
182 for (
int i = 0; i < num_tasks; ++i) {
183 TaskTime& ref = task_by_decreasing_start_max_[i];
187 task_by_decreasing_start_max_.end(),
188 std::greater<TaskTime>());
189 return task_by_decreasing_start_max_;
192 const std::vector<TaskTime>&
195 for (
int i = 0; i < num_tasks; ++i) {
196 TaskTime& ref = task_by_decreasing_end_max_[i];
200 task_by_decreasing_end_max_.end(), std::greater<TaskTime>());
201 return task_by_decreasing_end_max_;
204 const std::vector<TaskTime>&
207 if (new_timestamp > shifted_start_min_timestamp_) {
208 shifted_start_min_timestamp_ = new_timestamp;
210 bool is_sorted =
true;
212 for (
int i = 0; i < num_tasks; ++i) {
213 TaskTime& ref = task_by_increasing_shifted_start_min_[i];
215 is_sorted = is_sorted && ref.
time >= previous;
218 if (is_sorted)
return task_by_increasing_shifted_start_min_;
220 task_by_increasing_shifted_start_min_.end());
222 return task_by_increasing_shifted_start_min_;
228 AddOtherReason(before);
229 AddOtherReason(after);
235 integer_reason_.push_back(
237 integer_reason_.push_back(
240 integer_reason_.push_back(
255 const IntegerValue slack = end_min_lit.
bound + start_max_lit.
bound - 1;
257 integer_reason_.push_back(end_min_lit);
258 integer_reason_.push_back(start_max_lit);
262 slack, {IntegerValue(1), IntegerValue(1)},
263 {end_min_lit.
var, start_max_lit.
var}, &integer_reason_);
267 CHECK(other_helper_ ==
nullptr);
268 return integer_trail_->
Enqueue(
bound, literal_reason_, integer_reason_);
279 reason_for_presence_[t]) {
287 integer_reason_.push_back(
296 if (!integer_trail_->
Enqueue(lit, literal_reason_, integer_reason_)) {
304 bool SchedulingConstraintHelper::PushIntervalBound(
int t,
IntegerLiteral lit) {
311 IntegerValue new_min_start) {
312 return PushIntervalBound(
317 IntegerValue new_max_end) {
318 return PushIntervalBound(
329 literal_reason_.push_back(
Literal(reason_for_presence_[t]).Negated());
334 literal_reason_, integer_reason_);
340 return integer_trail_->
ReportConflict(literal_reason_, integer_reason_);
345 bool watch_start_max,
346 bool watch_end_max)
const {
347 const int num_tasks = start_vars_.size();
348 for (
int t = 0; t < num_tasks; ++t) {
351 if (watch_start_max) {
366 void SchedulingConstraintHelper::AddOtherReason(
int t) {
367 if (other_helper_ ==
nullptr || already_added_to_other_reasons_[t])
return;
368 already_added_to_other_reasons_[t] =
true;
373 void SchedulingConstraintHelper::ImportOtherReasons() {
374 if (other_helper_ !=
nullptr) ImportOtherReasons(*other_helper_);
377 void SchedulingConstraintHelper::ImportOtherReasons(
379 literal_reason_.insert(literal_reason_.end(),
380 other_helper.literal_reason_.begin(),
381 other_helper.literal_reason_.end());
382 integer_reason_.insert(integer_reason_.end(),
383 other_helper.integer_reason_.begin(),
384 other_helper.integer_reason_.end());