14#ifndef OR_TOOLS_SAT_NO_OVERLAP_2D_HELPER_H_
15#define OR_TOOLS_SAT_NO_OVERLAP_2D_HELPER_H_
22#include "absl/types/span.h"
41 std::vector<AffineExpression> x_ends,
42 std::vector<AffineExpression> x_sizes,
43 std::vector<LiteralIndex> x_reason_for_presence,
44 std::vector<AffineExpression> y_starts,
45 std::vector<AffineExpression> y_ends,
46 std::vector<AffineExpression> y_sizes,
47 std::vector<LiteralIndex> y_reason_for_presence,
49 : axes_are_swapped_(false),
51 x_starts, x_ends, x_sizes, x_reason_for_presence, model)),
53 y_starts, y_ends, y_sizes, y_reason_for_presence, model)),
56 const int num_boxes = x_helper_->NumTasks();
57 connected_components_.reserve(1, num_boxes);
58 connected_components_.Add({});
59 for (
int i = 0;
i < x_helper_->NumTasks(); ++
i) {
60 if (!x_helper_->IsAbsent(
i) && !y_helper_->IsAbsent(
i)) {
61 connected_components_.AppendToLastVector(
i);
69 bool y_is_forward_after_swap =
true,
70 bool swap_x_and_y =
false);
73 return x_helper_->IsOptional(index) || y_helper_->IsOptional(index);
77 return x_helper_->IsPresent(index) && y_helper_->IsPresent(index);
81 return x_helper_->IsAbsent(index) || y_helper_->IsAbsent(index);
85 return {.x_min = x_helper_->StartMin(index),
86 .x_max = x_helper_->EndMax(index),
87 .y_min = y_helper_->StartMin(index),
88 .y_max = y_helper_->EndMax(index)};
92 return {.x_min = x_helper_->LevelZeroStartMin(index),
93 .x_max = x_helper_->LevelZeroEndMax(index),
94 .y_min = y_helper_->LevelZeroStartMin(index),
95 .y_max = y_helper_->LevelZeroEndMax(index)};
99 return x_helper_->StartIsFixed(index) && x_helper_->EndIsFixed(index) &&
100 y_helper_->StartIsFixed(index) && y_helper_->EndIsFixed(index);
104 return {x_helper_->SizeMax(index), y_helper_->SizeMax(index)};
109 return {x_helper_->LevelZeroSizeMin(index),
110 y_helper_->LevelZeroSizeMin(index)};
114 x_helper_->ClearReason();
115 y_helper_->ClearReason();
152 absl::Span<const RectangleInRange> ranges);
171 x_helper_->AddStartMinReason(index, lower_bound);
185 x_helper_->AddStartMaxReason(index, upper_bound);
191 y_helper_->AddStartMinReason(index, lower_bound);
197 y_helper_->AddStartMaxReason(index, upper_bound);
201 x_helper_->AddPresenceReason(index);
202 y_helper_->AddPresenceReason(index);
206 x_helper_->ImportOtherReasons(*y_helper_);
207 return x_helper_->IncreaseStartMin(index, new_lower_bound);
211 x_helper_->ImportOtherReasons(*y_helper_);
212 return x_helper_->ReportConflict();
215 int NumBoxes()
const {
return x_helper_->NumTasks(); }
228 return connected_components_;
233 return level_zero_bound_change_idx_;
237 void Reset(absl::Span<const Rectangle> fixed_boxes,
238 absl::Span<const int> non_fixed_box_indexes);
242 bool axes_are_swapped_;
243 std::unique_ptr<SchedulingConstraintHelper> x_helper_;
244 std::unique_ptr<SchedulingConstraintHelper> y_helper_;
245 std::unique_ptr<SchedulingDemandHelper> x_demands_helper_;
246 std::unique_ptr<SchedulingDemandHelper> y_demands_helper_;
249 std::vector<int> propagators_watching_;
250 int64_t inprocessing_count_ = 0;
251 int64_t level_zero_bound_change_idx_ = 0;
SchedulingConstraintHelper & y_helper() const
const CompactVectorVector< int > & connected_components() const
void RegisterWith(GenericLiteralWatcher *watcher)
bool ReportConflictFromTwoBoxes(int box1, int box2)
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
In SWIG mode, we don't want anything besides these top-level includes.