Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
2d_orthogonal_packing_testing.cc
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
15
16#include <algorithm>
17#include <utility>
18#include <vector>
19
20#include "absl/log/check.h"
21#include "absl/random/bit_gen_ref.h"
22#include "absl/random/distributions.h"
23#include "absl/types/span.h"
25#include "ortools/sat/integer.h"
26
27namespace operations_research {
28namespace sat {
29
30std::vector<Rectangle> GenerateNonConflictingRectangles(
31 int num_rectangles, absl::BitGenRef random) {
32 static constexpr int kSizeMax = 1'000'000;
33 std::vector<Rectangle> rectangles;
34 rectangles.reserve(num_rectangles);
35 rectangles.push_back(
36 {.x_min = 0, .x_max = kSizeMax, .y_min = 0, .y_max = kSizeMax});
37 for (int i = 0; i < num_rectangles; ++i) {
38 std::swap(rectangles.back(),
39 rectangles[absl::Uniform(random, 0ull, rectangles.size() - 1)]);
40 const Rectangle& rec = rectangles.back();
41 if (absl::Bernoulli(random, 0.5)) {
42 const IntegerValue cut = IntegerValue(
43 absl::Uniform(random, rec.x_min.value(), rec.x_max.value()));
44 const Rectangle new_range = {.x_min = rec.x_min,
45 .x_max = cut,
46 .y_min = rec.y_min,
47 .y_max = rec.y_max};
48 const Rectangle new_range2 = {.x_min = cut,
49 .x_max = rec.x_max,
50 .y_min = rec.y_min,
51 .y_max = rec.y_max};
52 rectangles.pop_back();
53 rectangles.push_back(new_range);
54 rectangles.push_back(new_range2);
55 } else {
56 const IntegerValue cut = IntegerValue(
57 absl::Uniform(random, rec.y_min.value(), rec.y_max.value()));
58 const Rectangle new_range = {.x_min = rec.x_min,
59 .x_max = rec.x_max,
60 .y_min = rec.y_min,
61 .y_max = cut};
62 const Rectangle new_range2 = {.x_min = rec.x_min,
63 .x_max = rec.x_max,
64 .y_min = cut,
65 .y_max = rec.y_max};
66 rectangles.pop_back();
67 rectangles.push_back(new_range);
68 rectangles.push_back(new_range2);
69 }
70 }
71 return rectangles;
72}
73
74std::vector<RectangleInRange> MakeItemsFromRectangles(
75 absl::Span<const Rectangle> rectangles, double slack_factor,
76 absl::BitGenRef random) {
77 IntegerValue size_max_x = 0;
78 IntegerValue size_max_y = 0;
79 for (const Rectangle& rec : rectangles) {
80 size_max_x = std::max(size_max_x, rec.SizeX());
81 size_max_y = std::max(size_max_y, rec.SizeY());
82 }
83 std::vector<RectangleInRange> ranges;
84 ranges.reserve(rectangles.size());
85 const int max_slack_x = slack_factor * size_max_x.value();
86 const int max_slack_y = slack_factor * size_max_y.value();
87 for (const Rectangle& rec : rectangles) {
89 range.x_size = rec.x_max - rec.x_min;
90 range.y_size = rec.y_max - rec.y_min;
91 range.bounding_area = {
92 .x_min =
93 rec.x_min - IntegerValue(absl::Uniform(random, 0, max_slack_x)),
94 .x_max =
95 rec.x_max + IntegerValue(absl::Uniform(random, 0, max_slack_x)),
96 .y_min =
97 rec.y_min - IntegerValue(absl::Uniform(random, 0, max_slack_y)),
98 .y_max =
99 rec.y_max + IntegerValue(absl::Uniform(random, 0, max_slack_y))};
100 ranges.push_back(range);
101 }
102 return ranges;
103}
104
105std::vector<ItemForPairwiseRestriction>
107 const std::vector<Rectangle>& rectangles, double slack_factor,
108 absl::BitGenRef random) {
109 const std::vector<RectangleInRange> range_items =
110 MakeItemsFromRectangles(rectangles, slack_factor, random);
111 std::vector<ItemForPairwiseRestriction> items;
112 items.reserve(rectangles.size());
113 for (int i = 0; i < range_items.size(); ++i) {
114 const RectangleInRange& rec = range_items[i];
115 items.push_back({.index = i,
116 .x = {.start_min = rec.bounding_area.x_min,
117 .start_max = rec.bounding_area.x_max - rec.x_size,
118 .end_min = rec.bounding_area.x_min + rec.x_size,
119 .end_max = rec.bounding_area.x_max},
120 .y = {.start_min = rec.bounding_area.y_min,
121 .start_max = rec.bounding_area.y_max - rec.y_size,
122 .end_min = rec.bounding_area.y_min + rec.y_size,
123 .end_max = rec.bounding_area.y_max}});
124 }
125 return items;
126}
127
128std::vector<ItemForPairwiseRestriction>
130 double slack_factor,
131 absl::BitGenRef random) {
132 const std::vector<Rectangle> rectangles =
133 GenerateNonConflictingRectangles(num_rectangles, random);
134 std::vector<ItemForPairwiseRestriction> items =
135 GenerateItemsRectanglesWithNoPairwiseConflict(rectangles, slack_factor,
136 random);
137 bool done = false;
138 // Now run the propagator until there is no more pairwise conditions.
139 do {
140 std::vector<PairwiseRestriction> results;
141 AppendPairwiseRestrictions(items, &results);
142 for (const PairwiseRestriction& restriction : results) {
143 CHECK(restriction.type !=
145 // Remove the slack we added
146 for (int index : {restriction.first_index, restriction.second_index}) {
147 const auto& rec = rectangles[index];
148 items[index] = {.index = index,
149 .x = {.start_min = rec.x_min,
150 .start_max = rec.x_min,
151 .end_min = rec.x_max,
152 .end_max = rec.x_max},
153 .y = {.start_min = rec.y_min,
154 .start_max = rec.y_min,
155 .end_min = rec.y_max,
156 .end_max = rec.y_max}};
157 }
158 }
159 done = results.empty();
160 } while (!done);
161 return items;
162}
163
164} // namespace sat
165} // namespace operations_research
int index
std::vector< Rectangle > GenerateNonConflictingRectangles(int num_rectangles, absl::BitGenRef random)
void AppendPairwiseRestrictions(absl::Span< const ItemForPairwiseRestriction > items, std::vector< PairwiseRestriction > *result)
std::vector< ItemForPairwiseRestriction > GenerateItemsRectanglesWithNoPairwisePropagation(int num_rectangles, double slack_factor, absl::BitGenRef random)
std::vector< ItemForPairwiseRestriction > GenerateItemsRectanglesWithNoPairwiseConflict(const std::vector< Rectangle > &rectangles, double slack_factor, absl::BitGenRef random)
std::vector< RectangleInRange > MakeItemsFromRectangles(absl::Span< const Rectangle > rectangles, double slack_factor, absl::BitGenRef random)
In SWIG mode, we don't want anything besides these top-level includes.
const std::optional< Range > & range
Definition statistics.cc:37