14#ifndef ORTOOLS_SAT_NO_OVERLAP_2D_HELPER_H_
15#define ORTOOLS_SAT_NO_OVERLAP_2D_HELPER_H_
22#include "absl/types/span.h"
43 std::vector<AffineExpression> x_ends,
44 std::vector<AffineExpression> x_sizes,
45 std::vector<LiteralIndex> x_reason_for_presence,
46 std::vector<AffineExpression> y_starts,
47 std::vector<AffineExpression> y_ends,
48 std::vector<AffineExpression> y_sizes,
49 std::vector<LiteralIndex> y_reason_for_presence,
51 : axes_are_swapped_(false),
53 x_starts, x_ends, x_sizes, x_reason_for_presence, model)),
55 y_starts, y_ends, y_sizes, y_reason_for_presence, model)),
60 const int num_boxes = x_helper_->NumTasks();
61 connected_components_.reserve(1, num_boxes);
62 connected_components_.Add({});
63 for (
int i = 0;
i < x_helper_->NumTasks(); ++
i) {
64 if (!x_helper_->IsAbsent(
i) && !y_helper_->IsAbsent(
i)) {
65 connected_components_.AppendToLastVector(
i);
71 absl::Span<const Literal> enforcement_literals);
74 bool y_is_forward_after_swap =
true,
75 bool swap_x_and_y =
false);
78 return x_helper_->IsOptional(index) || y_helper_->IsOptional(index);
82 return x_helper_->IsPresent(index) && y_helper_->IsPresent(index);
86 return x_helper_->IsAbsent(index) || y_helper_->IsAbsent(index);
90 return {.x_min = x_helper_->StartMin(index),
91 .x_max = x_helper_->EndMax(index),
92 .y_min = y_helper_->StartMin(index),
93 .y_max = y_helper_->EndMax(index)};
97 return {.x_min = x_helper_->LevelZeroStartMin(index),
98 .x_max = x_helper_->LevelZeroEndMax(index),
99 .y_min = y_helper_->LevelZeroStartMin(index),
100 .y_max = y_helper_->LevelZeroEndMax(index)};
104 return x_helper_->StartIsFixed(index) && x_helper_->EndIsFixed(index) &&
105 y_helper_->StartIsFixed(index) && y_helper_->EndIsFixed(index);
109 return {x_helper_->SizeMax(index), y_helper_->SizeMax(index)};
114 return {x_helper_->LevelZeroSizeMin(index),
115 y_helper_->LevelZeroSizeMin(index)};
121 x_helper_->ResetReason();
122 y_helper_->ResetReason();
159 absl::Span<const RectangleInRange> ranges);
178 x_helper_->AddStartMinReason(index, lower_bound);
192 x_helper_->AddStartMaxReason(index, upper_bound);
198 y_helper_->AddStartMinReason(index, lower_bound);
204 y_helper_->AddStartMaxReason(index, upper_bound);
208 x_helper_->AddPresenceReason(index);
209 y_helper_->AddPresenceReason(index);
213 x_helper_->ImportReasonsFromOther(*y_helper_);
214 return x_helper_->IncreaseStartMin(index, new_lower_bound);
218 x_helper_->ImportReasonsFromOther(*y_helper_);
219 return x_helper_->ReportConflict();
222 int NumBoxes()
const {
return x_helper_->NumTasks(); }
235 return connected_components_;
240 return level_zero_bound_change_idx_;
244 void Reset(absl::Span<const Rectangle> fixed_boxes,
245 absl::Span<const int> non_fixed_box_indexes);
249 bool axes_are_swapped_;
250 std::unique_ptr<SchedulingConstraintHelper> x_helper_;
251 std::unique_ptr<SchedulingConstraintHelper> y_helper_;
252 std::unique_ptr<SchedulingDemandHelper> x_demands_helper_;
253 std::unique_ptr<SchedulingDemandHelper> y_demands_helper_;
255 EnforcementId enforcement_id_;
258 std::vector<int> propagators_watching_;
259 int64_t inprocessing_count_ = 0;
260 int64_t level_zero_bound_change_idx_ = 0;
SchedulingConstraintHelper & y_helper() const
const CompactVectorVector< int > & connected_components() const
bool ReportConflictFromTwoBoxes(int box1, int box2)
void RegisterWith(GenericLiteralWatcher *watcher, absl::Span< const Literal > enforcement_literals)
int64_t LastLevelZeroChangeIdx() const
SchedulingDemandHelper & y_demands_helper()
void AddSizeMinReason(int index)
bool SynchronizeAndSetDirection(bool x_is_forward_after_swap=true, bool y_is_forward_after_swap=true, bool swap_x_and_y=false)
Rectangle GetLevelZeroBoundingRectangle(int index) const
void AddLeftMaxReason(int index, IntegerValue upper_bound)
bool IsFixed(int index) const
bool IsPresent(int index) const
bool ReportConflictFromInfeasibleBoxRanges(absl::Span< const RectangleInRange > ranges)
bool IsOptional(int index) const
void WatchAllBoxes(int id)
bool Propagate() override
bool IsAbsent(int index) const
std::pair< IntegerValue, IntegerValue > GetLevelZeroBoxSizesMin(int index) const
ItemWithVariableSize GetItemWithVariableSize(int index) const
int64_t InProcessingCount() const
void AddLeftMinReason(int index, IntegerValue lower_bound)
Rectangle GetBoundingRectangle(int index) const
NoOverlap2DConstraintHelper(std::vector< AffineExpression > x_starts, std::vector< AffineExpression > x_ends, std::vector< AffineExpression > x_sizes, std::vector< LiteralIndex > x_reason_for_presence, std::vector< AffineExpression > y_starts, std::vector< AffineExpression > y_ends, std::vector< AffineExpression > y_sizes, std::vector< LiteralIndex > y_reason_for_presence, Model *model)
bool PropagateRelativePosition(int first, int second, PairwiseRestriction::PairwiseRestrictionType type)
SchedulingDemandHelper & x_demands_helper()
RectangleInRange GetItemRangeForSizeMin(int index) const
void AddBottomMaxReason(int index, IntegerValue upper_bound)
void AddBottomMinReason(int index, IntegerValue lower_bound)
void AddPresenceReason(int index)
bool IncreaseLeftMin(int index, IntegerValue new_lower_bound)
std::pair< IntegerValue, IntegerValue > GetBoxSizesMax(int index) const
void AddYSizeMinReason(int index)
void AddXSizeMinReason(int index)
SchedulingConstraintHelper & x_helper() const
PropagatorInterface()=default