27 IntegerValue fixed_size,
28 LiteralIndex is_present) {
30 const IntervalVariable i(start_vars_.
size());
37 std::vector<Literal> enforcement_literals;
39 enforcement_literals.push_back(
Literal(is_present));
44 SizeVar(i), enforcement_literals);
49 enforcement_literals);
54 const std::vector<IntervalVariable>& tasks,
Model*
model)
61 minus_end_vars_.clear();
62 minus_start_vars_.clear();
65 reason_for_presence_.clear();
66 for (
const IntervalVariable i : tasks) {
67 if (repository->IsOptional(i)) {
68 reason_for_presence_.push_back(repository->IsPresentLiteral(i).Index());
74 fixed_sizes_.push_back(repository->MinSize(i));
76 size_vars_.push_back(repository->SizeVar(i));
77 fixed_sizes_.push_back(IntegerValue(0));
79 start_vars_.push_back(repository->StartVar(i));
80 end_vars_.push_back(repository->EndVar(i));
81 minus_start_vars_.push_back(
NegationOf(repository->StartVar(i)));
82 minus_end_vars_.push_back(
NegationOf(repository->EndVar(i)));
93 start_vars_.resize(num_tasks);
99 current_time_direction_ = other.current_time_direction_;
101 const int num_tasks = tasks.size();
102 start_vars_.resize(num_tasks);
103 end_vars_.resize(num_tasks);
104 minus_end_vars_.resize(num_tasks);
105 minus_start_vars_.resize(num_tasks);
106 size_vars_.resize(num_tasks);
107 fixed_sizes_.resize(num_tasks);
108 reason_for_presence_.resize(num_tasks);
109 for (
int i = 0; i < num_tasks; ++i) {
110 const int t = tasks[i];
111 start_vars_[i] = other.start_vars_[t];
112 end_vars_[i] = other.end_vars_[t];
113 minus_end_vars_[i] = other.minus_end_vars_[t];
114 minus_start_vars_[i] = other.minus_start_vars_[t];
115 size_vars_[i] = other.size_vars_[t];
116 fixed_sizes_[i] = other.fixed_sizes_[t];
117 reason_for_presence_[i] = other.reason_for_presence_[t];
123 void SchedulingConstraintHelper::InitSortedVectors() {
124 const int num_tasks = start_vars_.size();
125 task_by_increasing_start_min_.resize(num_tasks);
126 task_by_increasing_end_min_.resize(num_tasks);
127 task_by_decreasing_start_max_.resize(num_tasks);
128 task_by_decreasing_end_max_.resize(num_tasks);
129 task_by_increasing_shifted_start_min_.resize(num_tasks);
130 task_by_negated_shifted_end_max_.resize(num_tasks);
131 for (
int t = 0; t < num_tasks; ++t) {
132 task_by_increasing_start_min_[t].task_index = t;
133 task_by_increasing_end_min_[t].task_index = t;
134 task_by_decreasing_start_max_[t].task_index = t;
135 task_by_decreasing_end_max_[t].task_index = t;
136 task_by_increasing_shifted_start_min_[t].task_index = t;
137 task_by_negated_shifted_end_max_[t].task_index = t;
139 shifted_start_min_timestamp_ = -1;
140 negated_shifted_end_max_timestamp_ = -1;
144 if (current_time_direction_ == is_forward)
return;
145 current_time_direction_ = is_forward;
147 std::swap(start_vars_, minus_end_vars_);
148 std::swap(end_vars_, minus_start_vars_);
149 std::swap(task_by_increasing_start_min_, task_by_decreasing_end_max_);
150 std::swap(task_by_increasing_end_min_, task_by_decreasing_start_max_);
151 std::swap(task_by_increasing_shifted_start_min_,
152 task_by_negated_shifted_end_max_);
153 std::swap(shifted_start_min_timestamp_, negated_shifted_end_max_timestamp_);
156 const std::vector<TaskTime>&
159 for (
int i = 0; i < num_tasks; ++i) {
160 TaskTime& ref = task_by_increasing_start_min_[i];
164 task_by_increasing_start_min_.end());
165 return task_by_increasing_start_min_;
168 const std::vector<TaskTime>&
171 for (
int i = 0; i < num_tasks; ++i) {
172 TaskTime& ref = task_by_increasing_end_min_[i];
176 task_by_increasing_end_min_.end());
177 return task_by_increasing_end_min_;
180 const std::vector<TaskTime>&
183 for (
int i = 0; i < num_tasks; ++i) {
184 TaskTime& ref = task_by_decreasing_start_max_[i];
188 task_by_decreasing_start_max_.end(),
189 std::greater<TaskTime>());
190 return task_by_decreasing_start_max_;
193 const std::vector<TaskTime>&
196 for (
int i = 0; i < num_tasks; ++i) {
197 TaskTime& ref = task_by_decreasing_end_max_[i];
201 task_by_decreasing_end_max_.end(), std::greater<TaskTime>());
202 return task_by_decreasing_end_max_;
205 const std::vector<TaskTime>&
208 if (new_timestamp > shifted_start_min_timestamp_) {
209 shifted_start_min_timestamp_ = new_timestamp;
211 bool is_sorted =
true;
213 for (
int i = 0; i < num_tasks; ++i) {
214 TaskTime& ref = task_by_increasing_shifted_start_min_[i];
216 is_sorted = is_sorted && ref.
time >= previous;
219 if (is_sorted)
return task_by_increasing_shifted_start_min_;
221 task_by_increasing_shifted_start_min_.end());
223 return task_by_increasing_shifted_start_min_;
229 AddOtherReason(before);
230 AddOtherReason(after);
236 integer_reason_.push_back(
238 integer_reason_.push_back(
241 integer_reason_.push_back(
256 const IntegerValue slack = end_min_lit.
bound + start_max_lit.
bound - 1;
258 integer_reason_.push_back(end_min_lit);
259 integer_reason_.push_back(start_max_lit);
263 slack, {IntegerValue(1), IntegerValue(1)},
264 {end_min_lit.
var, start_max_lit.
var}, &integer_reason_);
268 CHECK(other_helper_ ==
nullptr);
269 return integer_trail_->
Enqueue(lit, literal_reason_, integer_reason_);
280 reason_for_presence_[t]) {
288 integer_reason_.push_back(
297 if (!integer_trail_->
Enqueue(lit, literal_reason_, integer_reason_)) {
305 bool SchedulingConstraintHelper::PushIntervalBound(
int t,
IntegerLiteral lit) {
312 IntegerValue new_min_start) {
313 return PushIntervalBound(
318 IntegerValue new_max_end) {
319 return PushIntervalBound(
330 literal_reason_.push_back(
Literal(reason_for_presence_[t]).Negated());
335 literal_reason_, integer_reason_);
346 literal_reason_.push_back(
Literal(reason_for_presence_[t]));
351 literal_reason_, integer_reason_);
357 return integer_trail_->
ReportConflict(literal_reason_, integer_reason_);
362 bool watch_start_max,
363 bool watch_end_max)
const {
364 const int num_tasks = start_vars_.size();
365 for (
int t = 0; t < num_tasks; ++t) {
368 if (watch_start_max) {
383 void SchedulingConstraintHelper::AddOtherReason(
int t) {
384 if (other_helper_ ==
nullptr || already_added_to_other_reasons_[t])
return;
385 already_added_to_other_reasons_[t] =
true;
390 void SchedulingConstraintHelper::ImportOtherReasons() {
391 if (other_helper_ !=
nullptr) ImportOtherReasons(*other_helper_);
394 void SchedulingConstraintHelper::ImportOtherReasons(
396 literal_reason_.insert(literal_reason_.end(),
397 other_helper.literal_reason_.begin(),
398 other_helper.literal_reason_.end());
399 integer_reason_.insert(integer_reason_.end(),
400 other_helper.integer_reason_.begin(),
401 other_helper.integer_reason_.end());
405 return absl::StrCat(
"t=", t,
" is_present=",
IsPresent(t),