14#ifndef ORTOOLS_SAT_2D_RECTANGLE_PRESOLVE_H_
15#define ORTOOLS_SAT_2D_RECTANGLE_PRESOLVE_H_
21#include "absl/algorithm/container.h"
22#include "absl/container/flat_hash_map.h"
23#include "absl/container/inlined_vector.h"
24#include "absl/log/log.h"
25#include "absl/types/span.h"
39 absl::Span<const RectangleInRange> non_fixed_boxes,
40 std::vector<Rectangle>* fixed_boxes);
103 absl::Span<const RectangleInRange> non_fixed_boxes,
104 absl::Span<const Rectangle> fixed_boxes,
int max_num_components);
120 std::vector<Rectangle>* optional_rectangles);
127 std::vector<Rectangle>* mandatory_rectangles,
128 std::vector<Rectangle>* optional_rectangles);
132template <
typename Sink>
139 sink.Append(
"RIGHT");
142 sink.Append(
"BOTTOM");
176 return std::tie(a.
x_min, a.
x_max) > std::tie(
b.x_min,
b.x_max);
178 return std::tie(a.
x_min, a.
x_max) < std::tie(
b.x_min,
b.x_max);
180 return std::tie(a.
y_min, a.
y_max) < std::tie(
b.y_min,
b.y_max);
182 return std::tie(a.
y_min, a.
y_max) > std::tie(
b.y_min,
b.y_max);
184 LOG(FATAL) <<
"Invalid edge position: " <<
static_cast<int>(
edge_);
190 absl::Span<const Rectangle> rectangles,
191 absl::Span<
const std::tuple<int, EdgePosition, int>> neighbors)
192 : size_(rectangles.size()) {
193 for (
const auto& [box_index, edge, neighbor] : neighbors) {
194 neighbors_[edge][box_index].push_back(neighbor);
196 for (
int edge = 0; edge < 4; ++edge) {
197 for (
auto& [box_index, neighbors] : neighbors_[edge]) {
198 absl::c_sort(neighbors, [&rectangles, edge](
int a,
int b) {
200 rectangles[a], rectangles[
b]);
211 if (
auto it = neighbors_[edge].find(rectangle_index);
212 it != neighbors_[edge].end()) {
220 absl::flat_hash_map<int, absl::InlinedVector<int, 3>> neighbors_[4];
227 const Neighbours& neighbours);
250std::vector<SingleShape>
BoxesToShapes(absl::Span<const Rectangle> rectangles,
CompareClockwise(EdgePosition edge)
bool operator()(const Rectangle &a, const Rectangle &b) const
int NumRectangles() const
absl::Span< const int > GetSortedNeighbors(int rectangle_index, EdgePosition edge) const
Neighbours(absl::Span< const Rectangle > rectangles, absl::Span< const std::tuple< int, EdgePosition, int > > neighbors)
bool ReduceNumberOfBoxesExactMandatory(std::vector< Rectangle > *mandatory_rectangles, std::vector< Rectangle > *optional_rectangles)
std::vector< std::vector< int > > SplitInConnectedComponents(const Neighbours &neighbours)
std::vector< SingleShape > BoxesToShapes(absl::Span< const Rectangle > rectangles, const Neighbours &neighbours)
Disjoint2dPackingResult DetectDisjointRegionIn2dPacking(absl::Span< const RectangleInRange > non_fixed_boxes, absl::Span< const Rectangle > fixed_boxes, int max_num_components)
bool ReduceNumberofBoxesGreedy(std::vector< Rectangle > *mandatory_rectangles, std::vector< Rectangle > *optional_rectangles)
std::vector< Rectangle > CutShapeIntoRectangles(SingleShape shape)
void AbslStringify(Sink &sink, EdgePosition e)
Neighbours BuildNeighboursGraph(absl::Span< const Rectangle > rectangles)
bool PresolveFixed2dRectangles(absl::Span< const RectangleInRange > non_fixed_boxes, std::vector< Rectangle > *fixed_boxes)
std::vector< Rectangle > bin_area
std::vector< Rectangle > fixed_boxes
std::vector< int > non_fixed_box_indexes
std::vector< std::pair< IntegerValue, IntegerValue > > step_points
std::vector< int > touching_box_index
std::vector< ShapePath > holes