Skip to content

Commit 252e707

Browse files
committed
Improve defects handling in rectangleguillotine
1 parent 4a52240 commit 252e707

File tree

5 files changed

+133
-110
lines changed

5 files changed

+133
-110
lines changed

scripts/visualize_rectangleguillotine.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
if t == -4: # Defect.
4040
defects_x[i] += [x1, x2, x2, x1, x1, None]
4141
defects_y[i] += [y1, y1, y2, y2, y1, None]
42-
if not parent: # Bin.
42+
elif not parent: # Bin.
4343
bins_x.append([])
4444
bins_y.append([])
4545
trims_x.append([])
@@ -93,6 +93,20 @@
9393
row=i + 1,
9494
col=1)
9595

96+
fig.add_trace(go.Scatter(
97+
x=defects_x[i],
98+
y=defects_y[i],
99+
name="Defects",
100+
legendgroup="defects",
101+
showlegend=(i == 0),
102+
fillcolor="crimson",
103+
fill="toself",
104+
marker=dict(
105+
color='black',
106+
size=1)),
107+
row=i + 1,
108+
col=1)
109+
96110
fig.add_trace(go.Scatter(
97111
x=trims_x[i],
98112
y=trims_y[i],
@@ -118,20 +132,6 @@
118132
row=i + 1,
119133
col=1)
120134

121-
fig.add_trace(go.Scatter(
122-
x=defects_x[i],
123-
y=defects_y[i],
124-
name="Defects",
125-
legendgroup="defects",
126-
showlegend=(i == 0),
127-
fillcolor="crimson",
128-
fill="toself",
129-
marker=dict(
130-
color='black',
131-
size=1)),
132-
row=i + 1,
133-
col=1)
134-
135135
fig.add_trace(go.Scatter(
136136
x=items_x[i],
137137
y=items_y[i],

src/rectangleguillotine/branching_scheme.cpp

+104-91
Original file line numberDiff line numberDiff line change
@@ -188,69 +188,57 @@ bool BranchingScheme::better(
188188
Length BranchingScheme::x1_prev(const Node& node, Depth df) const
189189
{
190190
switch (df) {
191-
case -2: {
192-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
193-
return instance().left_trim(
194-
instance().bin_type(bin_type_id),
195-
CutOrientation::Horizontal);
196-
} case -1: {
197-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
198-
return instance().left_trim(
199-
instance().bin_type(bin_type_id),
200-
CutOrientation::Vertical);
201-
} case 0: {
191+
case 0: {
202192
return node.x1_curr + instance().parameters().cut_thickness;
203193
} case 1: {
204194
return node.x1_prev;
205195
} case 2: {
206196
return node.x1_prev;
207197
} default: {
208-
assert(false);
209-
return -1;
198+
BinPos bin_pos = node.number_of_bins + std::ceil(std::fabs(df) / 2) - 1;
199+
BinTypeId bin_type_id = instance().bin_type_id(bin_pos);
200+
if (std::abs(df) % 2 == 0) {
201+
return instance().left_trim(
202+
instance().bin_type(bin_type_id),
203+
CutOrientation::Horizontal);
204+
} else {
205+
return instance().left_trim(
206+
instance().bin_type(bin_type_id),
207+
CutOrientation::Vertical);
208+
}
210209
}
211210
}
212211
}
213212

214213
Length BranchingScheme::x3_prev(const Node& node, Depth df) const
215214
{
216215
switch (df) {
217-
case -2: {
218-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
219-
return instance().left_trim(
220-
instance().bin_type(bin_type_id),
221-
CutOrientation::Horizontal);
222-
} case -1: {
223-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
224-
return instance().left_trim(
225-
instance().bin_type(bin_type_id),
226-
CutOrientation::Vertical);
227-
} case 0: {
216+
case 0: {
228217
return node.x1_curr + instance().parameters().cut_thickness;
229218
} case 1: {
230219
return node.x1_prev;
231220
} case 2: {
232221
return node.x3_curr + instance().parameters().cut_thickness;
233222
} default: {
234-
assert(false);
235-
return -1;
223+
BinPos bin_pos = node.number_of_bins + std::ceil(std::fabs(df) / 2) - 1;
224+
BinTypeId bin_type_id = instance().bin_type_id(bin_pos);
225+
if (std::abs(df) % 2 == 0) {
226+
return instance().left_trim(
227+
instance().bin_type(bin_type_id),
228+
CutOrientation::Horizontal);
229+
} else {
230+
return instance().left_trim(
231+
instance().bin_type(bin_type_id),
232+
CutOrientation::Vertical);
233+
}
236234
}
237235
}
238236
}
239237

240238
Length BranchingScheme::y2_prev(const Node& node, Depth df) const
241239
{
242240
switch (df) {
243-
case -2: {
244-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
245-
return instance().bottom_trim(
246-
instance().bin_type(bin_type_id),
247-
CutOrientation::Horizontal);
248-
} case -1: {
249-
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins);
250-
return instance().bottom_trim(
251-
instance().bin_type(bin_type_id),
252-
CutOrientation::Vertical);
253-
} case 0: {
241+
case 0: {
254242
BinTypeId bin_type_id = instance().bin_type_id(node.number_of_bins - 1);
255243
return instance().bottom_trim(
256244
instance().bin_type(bin_type_id),
@@ -260,31 +248,40 @@ Length BranchingScheme::y2_prev(const Node& node, Depth df) const
260248
} case 2: {
261249
return node.y2_prev;
262250
} default: {
263-
assert(false);
264-
return -1;
251+
BinPos bin_pos = node.number_of_bins + std::ceil(std::fabs(df) / 2) - 1;
252+
BinTypeId bin_type_id = instance().bin_type_id(bin_pos);
253+
if (std::abs(df) % 2 == 0) {
254+
return instance().bottom_trim(
255+
instance().bin_type(bin_type_id),
256+
CutOrientation::Horizontal);
257+
} else {
258+
return instance().bottom_trim(
259+
instance().bin_type(bin_type_id),
260+
CutOrientation::Vertical);
261+
}
265262
}
266263
}
267264
}
268265

269266
BinPos BranchingScheme::last_bin(const Node& node, Depth df) const
270267
{
271-
if (df <= -1) {
272-
return node.number_of_bins;
273-
} else {
268+
if (df >= 0) {
274269
return node.number_of_bins - 1;
270+
} else {
271+
return node.number_of_bins + std::ceil(std::fabs(df) / 2) - 1;
275272
}
276273
}
277274

278275
CutOrientation BranchingScheme::last_bin_orientation(const Node& node, Depth df) const
279276
{
280-
switch (df) {
281-
case -1: {
282-
return CutOrientation::Vertical;
283-
} case -2: {
284-
return CutOrientation::Horizontal;
285-
} default: {
277+
if (df >= 0) {
286278
return node.first_stage_orientation;
287-
}
279+
} else {
280+
if (std::abs(df) % 2 == 0) {
281+
return CutOrientation::Horizontal;
282+
} else {
283+
return CutOrientation::Vertical;
284+
}
288285
}
289286
}
290287

@@ -293,11 +290,7 @@ BranchingScheme::Front BranchingScheme::front(
293290
const Insertion& insertion) const
294291
{
295292
switch (insertion.df) {
296-
case -1: case -2: {
297-
return {last_bin(node, insertion.df), last_bin_orientation(node, insertion.df),
298-
0, insertion.x3, insertion.x1,
299-
0, insertion.y2};
300-
} case 0: {
293+
case 0: {
301294
return {last_bin(node, insertion.df), last_bin_orientation(node, insertion.df),
302295
node.x1_curr, insertion.x3, insertion.x1,
303296
0, insertion.y2};
@@ -310,10 +303,9 @@ BranchingScheme::Front BranchingScheme::front(
310303
node.x1_prev, insertion.x3, insertion.x1,
311304
node.y2_prev, insertion.y2};
312305
} default: {
313-
assert(false);
314-
return {-1, CutOrientation::Vertical,
315-
-1, -1, -1,
316-
-1, -1};
306+
return {last_bin(node, insertion.df), last_bin_orientation(node, insertion.df),
307+
0, insertion.x3, insertion.x1,
308+
0, insertion.y2};
317309
}
318310
}
319311
}
@@ -366,11 +358,7 @@ BranchingScheme::Node BranchingScheme::child_tmp(
366358

367359
// Compute x1_prev and y2_prev.
368360
switch (insertion.df) {
369-
case -1: case -2: {
370-
node.x1_prev = instance().left_trim(bin_type, o);
371-
node.y2_prev = instance().bottom_trim(bin_type, o);
372-
break;
373-
} case 0: {
361+
case 0: {
374362
node.x1_prev = parent.x1_curr + instance().parameters().cut_thickness;
375363
node.y2_prev = instance().bottom_trim(bin_type, o);
376364
break;
@@ -383,8 +371,8 @@ BranchingScheme::Node BranchingScheme::child_tmp(
383371
node.y2_prev = parent.y2_prev;
384372
break;
385373
} default: {
386-
assert(false);
387-
break;
374+
node.x1_prev = instance().left_trim(bin_type, o);
375+
node.y2_prev = instance().bottom_trim(bin_type, o);
388376
}
389377
}
390378

@@ -465,7 +453,25 @@ BranchingScheme::Node BranchingScheme::child_tmp(
465453
+ (node.x3_curr - node.x1_prev) * (node.y2_curr - node.y2_prev);
466454
}
467455
node.waste = node.current_area - node.item_area;
468-
assert(node.waste >= 0);
456+
if (node.waste < 0) {
457+
throw std::logic_error(
458+
"rectangleguillotine::BranchingScheme::child_tmp"
459+
"; node.waste: " + std::to_string(node.waste)
460+
+ "; node.current_area: " + std::to_string(node.current_area)
461+
+ "; node.item_area: " + std::to_string(node.item_area)
462+
+ "; parent.number_of_bins: " + std::to_string(parent.number_of_bins)
463+
+ "; node.number_of_bins: " + std::to_string(node.number_of_bins)
464+
+ "; node.df: " + std::to_string(node.df)
465+
+ "; node.number_of_items: " + std::to_string(node.number_of_items)
466+
+ "; node.item_type_id_1: " + std::to_string(node.item_type_id_1)
467+
+ "; node.item_type_id_2: " + std::to_string(node.item_type_id_2)
468+
+ "; w: " + std::to_string(w)
469+
+ "; h: " + std::to_string(h)
470+
+ "; node.x1_curr: " + std::to_string(node.x1_curr)
471+
+ "; node.y2_curr: " + std::to_string(node.y2_curr)
472+
+ "; node.x3_curr: " + std::to_string(node.x3_curr)
473+
+ ".");
474+
}
469475
return node;
470476
}
471477

@@ -641,15 +647,20 @@ const std::vector<BranchingScheme::Insertion>& BranchingScheme::insertions(
641647
}
642648

643649
// Try inserting a defect.
644-
BinTypeId bin_type_id = instance().bin_type_id(i);
645-
const BinType& bin_type = instance().bin_type(bin_type_id);
646-
for (DefectId defect_id = 0;
647-
defect_id < (DefectId)bin_type.defects.size();
648-
++defect_id) {
649-
const Defect& defect = bin_type.defects[defect_id];
650-
if (instance().right(defect, o) >= x
651-
&& instance().top(defect, o) >= y) {
652-
insertion_defect(parent, defect_id, df);
650+
if (parent.parent == nullptr
651+
|| parent.item_type_id_1 != -1
652+
|| parent.item_type_id_2 != -1
653+
|| parent.df < df) {
654+
BinTypeId bin_type_id = instance().bin_type_id(i);
655+
const BinType& bin_type = instance().bin_type(bin_type_id);
656+
for (DefectId defect_id = 0;
657+
defect_id < (DefectId)bin_type.defects.size();
658+
++defect_id) {
659+
const Defect& defect = bin_type.defects[defect_id];
660+
if (instance().right(defect, o) >= x
661+
&& instance().top(defect, o) >= y) {
662+
insertion_defect(parent, defect_id, df);
663+
}
653664
}
654665
}
655666
}
@@ -687,15 +698,7 @@ Area BranchingScheme::waste(
687698
Length BranchingScheme::x1_max(const Node& node, Depth df) const
688699
{
689700
switch (df) {
690-
case -1: case -2: {
691-
BinTypeId bin_type_id = instance().bin_type_id(i);
692-
const BinType& bin_type = instance().bin_type(bin_type_id);
693-
Length x = instance().width(bin_type, o) - instance().right_trim(bin_type, o);
694-
if (instance().parameters().maximum_distance_1_cuts != -1)
695-
if (x > x1_prev(node, df) + instance().parameters().maximum_distance_1_cuts)
696-
x = x1_prev(node, df) + instance().parameters().maximum_distance_1_cuts;
697-
return x;
698-
} case 0: {
701+
case 0: {
699702
BinTypeId bin_type_id = instance().bin_type_id(i);
700703
const BinType& bin_type = instance().bin_type(bin_type_id);
701704
Length x = instance().width(bin_type, o) - instance().right_trim(bin_type, o);
@@ -718,7 +721,13 @@ Length BranchingScheme::x1_max(const Node& node, Depth df) const
718721
} case 2: {
719722
return node.x1_max;
720723
} default: {
721-
return -1;
724+
BinTypeId bin_type_id = instance().bin_type_id(i);
725+
const BinType& bin_type = instance().bin_type(bin_type_id);
726+
Length x = instance().width(bin_type, o) - instance().right_trim(bin_type, o);
727+
if (instance().parameters().maximum_distance_1_cuts != -1)
728+
if (x > x1_prev(node, df) + instance().parameters().maximum_distance_1_cuts)
729+
x = x1_prev(node, df) + instance().parameters().maximum_distance_1_cuts;
730+
return x;
722731
}
723732
}
724733
}
@@ -763,7 +772,7 @@ void BranchingScheme::insertion_1_item(
763772
bool rotate,
764773
Depth df) const
765774
{
766-
assert(-2 <= df); assert(df <= 3);
775+
assert(df <= 3);
767776

768777
// Check defect intersection
769778
const rectangleguillotine::ItemType& item_type = instance().item_type(item_type_id);
@@ -832,7 +841,7 @@ void BranchingScheme::insertion_2_items(
832841
bool rotate2,
833842
Depth df) const
834843
{
835-
assert(-2 <= df); assert(df <= 3);
844+
assert(df <= 3);
836845

837846
// Check defect intersection
838847
const ItemType& item_type_1 = instance().item_type(item_type_id_1);
@@ -880,7 +889,6 @@ void BranchingScheme::insertion_defect(
880889
DefectId defect_id,
881890
Depth df) const
882891
{
883-
assert(-2 <= df);
884892
assert(df <= 3);
885893

886894
// Check defect intersection
@@ -1538,7 +1546,8 @@ Solution BranchingScheme::to_solution(
15381546
cut_position = subplate2_curr_y2 - (
15391547
(w_tmp == instance().item_type(current_node->item_type_id_2).rect.w)?
15401548
instance().item_type(current_node->item_type_id_2).rect.h:
1541-
instance().item_type(current_node->item_type_id_2).rect.w);
1549+
instance().item_type(current_node->item_type_id_2).rect.w)
1550+
- instance().parameters().cut_thickness;
15421551
}
15431552
solution_builder.add_node(d, cut_position);
15441553
if (current_node->item_type_id_1 != -1)
@@ -1636,8 +1645,12 @@ std::ostream& packingsolver::rectangleguillotine::operator<<(
16361645
std::ostream& os,
16371646
const BranchingScheme::Node& node)
16381647
{
1639-
os << "number_of_items " << node.number_of_items
1648+
os << "id " << node.id
1649+
<< " parent " << ((node.parent != nullptr)? node.parent->id: -1)
1650+
<< " number_of_items " << node.number_of_items
16401651
<< " number_of_bins " << node.number_of_bins
1652+
<< " item_type_id_1 " << node.item_type_id_1
1653+
<< " item_type_id_2 " << node.item_type_id_2
16411654
<< std::endl;
16421655
os << "item_area " << node.item_area
16431656
<< " current_area " << node.current_area
@@ -1655,7 +1668,7 @@ std::ostream& packingsolver::rectangleguillotine::operator<<(
16551668
os << "pos_stack" << std::flush;
16561669
for (ItemPos j_pos: node.pos_stack)
16571670
os << " " << j_pos;
1658-
os << std::endl;
1671+
//os << std::endl;
16591672

16601673
return os;
16611674
}

0 commit comments

Comments
 (0)