Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bottom and left soft trims in rectangleguillotine #156

Merged
merged 1 commit into from
Mar 4, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix bottom and left soft trims in rectangleguillotine
fontanf committed Mar 4, 2025
commit 1cd49f52e80a809d7a1fe57a69f0ec0b72d36e73
11 changes: 11 additions & 0 deletions data/rectangleguillotine/users/2025-03-04/bins.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
ID,WIDTH,HEIGHT,LEFT_TRIM,LEFT_TRIM_TYPE,RIGHT_TRIM,RIGHT_TRIM_TYPE,BOTTOM_TRIM,BOTTOM_TRIM_TYPE,TOP_TRIM,TOP_TRIM_TYPE
0,6000,3210,200,1,200,0,200,1,200,0
1,6000,3210,200,1,200,0,200,1,200,0
2,6000,3210,200,1,200,0,200,1,200,0
3,6000,3210,200,1,200,0,200,1,200,0
4,6000,3210,200,1,200,0,200,1,200,0
5,6000,3210,200,1,200,0,200,1,200,0
6,6000,3210,200,1,200,0,200,1,200,0
7,6000,3210,200,1,200,0,200,1,200,0
8,6000,3210,200,1,200,0,200,1,200,0
9,6000,3210,200,1,200,0,200,1,200,0
16 changes: 16 additions & 0 deletions data/rectangleguillotine/users/2025-03-04/items.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ID,WIDTH,HEIGHT,STACK_ID
0,950,885,4
1,950,885,5
2,950,885,6
3,950,885,7
4,950,885,8
5,715,1515,0
6,950,885,9
7,904,805,10
8,904,805,11
9,904,805,12
10,904,805,13
11,715,1515,1
12,904,805,14
13,950,885,2
14,950,885,3
10 changes: 10 additions & 0 deletions data/rectangleguillotine/users/2025-03-04/parameters.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
NAME,VALUE
objective,bin-packing-with-leftovers
number_of_stages,3
cut_type,exact
first_stage_orientation,vertical
min_waste,15
min1cut,20
max1cut,2500
cut_thickness,0
cut-through-defect,1
64 changes: 64 additions & 0 deletions data/rectangleguillotine/users/2025-03-04/solution.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
PLATE_ID,NODE_ID,X,Y,WIDTH,HEIGHT,TYPE,CUT,PARENT
0,0,0,0,6000,3210,0,0,
0,1,5800,3010,200,200,-1,-1,0
0,2,5800,0,200,3010,-1,-1,0
0,3,0,3010,5800,200,-1,-1,0
0,4,0,0,5800,3010,-2,0,0
0,5,0,0,200,3010,-1,1,4
0,6,200,0,805,3010,-2,1,4
0,7,200,0,805,200,-1,2,6
0,8,200,200,805,904,-2,2,6
0,9,200,200,805,904,-2,3,8
0,10,200,200,805,904,7,4,9
0,11,200,1104,805,904,-2,2,6
0,12,200,1104,805,904,-2,3,11
0,13,200,1104,805,904,8,4,12
0,14,200,2008,805,904,-2,2,6
0,15,200,2008,805,904,-2,3,14
0,16,200,2008,805,904,9,4,15
0,17,200,2912,805,98,-1,2,6
0,18,1005,0,950,3010,-2,1,4
0,19,1005,0,950,200,-1,2,18
0,20,1005,200,950,885,-2,2,18
0,21,1005,200,950,885,-2,3,20
0,22,1005,200,950,885,13,4,21
0,23,1005,1085,950,885,-2,2,18
0,24,1005,1085,950,885,-2,3,23
0,25,1005,1085,950,885,14,4,24
0,26,1005,1970,950,885,-2,2,18
0,27,1005,1970,950,885,-2,3,26
0,28,1005,1970,950,885,0,4,27
0,29,1005,2855,950,155,-1,2,18
0,30,1955,0,1808,3010,-2,1,4
0,31,1955,0,1808,200,-1,2,30
0,32,1955,200,1808,805,-2,2,30
0,33,1955,200,904,805,-2,3,32
0,34,1955,200,904,805,10,4,33
0,35,2859,200,904,805,-2,3,32
0,36,2859,200,904,805,12,4,35
0,37,1955,1005,1808,950,-2,2,30
0,38,1955,1005,885,950,-2,3,37
0,39,1955,1005,885,950,1,4,38
0,40,2840,1005,885,950,-2,3,37
0,41,2840,1005,885,950,2,4,40
0,42,3725,1005,38,950,-1,3,37
0,43,1955,1955,1808,950,-2,2,30
0,44,1955,1955,885,950,-2,3,43
0,45,1955,1955,885,950,3,4,44
0,46,2840,1955,885,950,-2,3,43
0,47,2840,1955,885,950,4,4,46
0,48,3725,1955,38,950,-1,3,43
0,49,1955,2905,1808,105,-1,2,30
0,50,3763,0,1430,3010,-2,1,4
0,51,3763,0,1430,200,-1,2,50
0,52,3763,200,1430,1515,-2,2,50
0,53,3763,200,715,1515,-2,3,52
0,54,3763,200,715,1515,5,4,53
0,55,4478,200,715,1515,-2,3,52
0,56,4478,200,715,1515,11,4,55
0,57,3763,1715,1430,885,-2,2,50
0,58,3763,1715,950,885,-2,3,57
0,59,3763,1715,950,885,6,4,58
0,60,4713,1715,480,885,-1,3,57
0,61,3763,2600,1430,410,-1,2,50
0,62,5193,0,607,3010,-3,1,4
48 changes: 29 additions & 19 deletions src/rectangleguillotine/branching_scheme.cpp
Original file line number Diff line number Diff line change
@@ -1059,7 +1059,7 @@ void BranchingScheme::update(
}

// Update insertion.x1 and insertion.z1 with respect to min1cut()
//std::cout << "update min1cut " << insertion << std::endl;
//std::cout << "- update min1cut " << insertion << std::endl;
if ((insertion.item_type_id_1 != -1 || insertion.item_type_id_2 != -1)
&& insertion.x1 - x1_prev(parent, insertion.df) < instance.parameters().minimum_distance_1_cuts) {
if (insertion.z1 == 0) {
@@ -1073,7 +1073,7 @@ void BranchingScheme::update(
}

// Update insertion.y2 and insertion.z2 with respect to min2cut()
//std::cout << "update min2cut " << insertion << std::endl;
//std::cout << "- update min2cut " << insertion << std::endl;
if ((insertion.item_type_id_1 != -1 || insertion.item_type_id_2 != -1)
&& insertion.y2 - y2_prev(parent, insertion.df) < instance.parameters().minimum_distance_2_cuts) {
if (insertion.z2 == 0) {
@@ -1089,7 +1089,7 @@ void BranchingScheme::update(
}

// Update insertion.y2 and insertion.z2 with respect to one2cut()
//std::cout << "update maximum_number_2_cuts " << insertion << std::endl;
//std::cout << "- update maximum_number_2_cuts " << insertion << std::endl;
if (instance.parameters().maximum_number_2_cuts != -1
&& insertion.df == 1
&& parent.subplate1curr_number_of_2_cuts == instance.parameters().maximum_number_2_cuts
@@ -1106,7 +1106,7 @@ void BranchingScheme::update(
}

// Update insertion.x1 if 2-staged
//std::cout << "update 2-staged " << insertion << std::endl;
//std::cout << "- update 2-staged " << insertion << std::endl;
if (instance.parameters().number_of_stages == 2 && insertion.x1 != w_physical) {
if (insertion.z1 == 0) {
if (insertion.x1 + cut_thickness + min_waste > w_physical)
@@ -1118,7 +1118,7 @@ void BranchingScheme::update(
}

// Update insertion.x1 and insertion.z1 with respect to x1_curr() and z1().
//std::cout << "update x1_curr " << insertion << std::endl;
//std::cout << "- update x1_curr " << insertion << std::endl;
if (insertion.df >= 1) {
if (insertion.z1 == 0) {
if (insertion.x1 + min_waste + cut_thickness <= parent.x1_curr) {
@@ -1151,7 +1151,7 @@ void BranchingScheme::update(
}

// Update insertion.y2 and insertion.z2 with respect to y2_curr() and z1().
//std::cout << "update y2_curr " << insertion << std::endl;
//std::cout << "- update y2_curr " << insertion << std::endl;
if (insertion.df == 2) {
if (insertion.z2 == 0) {
if (insertion.y2 + min_waste <= parent.y2_curr) {
@@ -1222,7 +1222,7 @@ void BranchingScheme::update(
}

// Update insertion.x1 and insertion.z1 with respect to defect intersections.
//std::cout << "update x1 defects " << insertion << std::endl;
//std::cout << "- update x1 defects " << insertion << std::endl;
if (!instance.parameters().cut_through_defects) {
for (;;) {
DefectId defect_id = instance.rect_intersects_defect(
@@ -1242,7 +1242,7 @@ void BranchingScheme::update(
}

// Check right soft-trim.
//std::cout << "update right soft-trim " << insertion << std::endl;
//std::cout << "- update right soft-trim " << insertion << std::endl;
if (insertion.x1 > w) {
if (insertion.x1 == w_physical) {
} else if (insertion.x1 < w_physical) {
@@ -1261,7 +1261,7 @@ void BranchingScheme::update(
}

// Increase width if too close from border
//std::cout << "update x border " << insertion << std::endl;
//std::cout << "- update x border " << insertion << std::endl;
if (insertion.x1 < w_physical
&& min_waste > 0
&& insertion.x1 + cut_thickness + min_waste > w_physical) {
@@ -1275,13 +1275,13 @@ void BranchingScheme::update(


// Check max width
//std::cout << "update max width " << insertion << std::endl;
//std::cout << "- update max width " << insertion << std::endl;
if (insertion.x1 > insertion.x1_max) {
return;
}

// Update insertion.y2 and insertion.z2 with respect to defect intersections.
//std::cout << "update y2 defects " << insertion << std::endl;
//std::cout << "- update y2 defects " << insertion << std::endl;
bool y2_fixed = (insertion.z2 == 2 || (insertion.df == 2 && parent.z2 == 2));

for (;;) {
@@ -1369,7 +1369,7 @@ void BranchingScheme::update(
}

// Check top soft-trim.
//std::cout << "update top soft-trim " << insertion << std::endl;
//std::cout << "- update top soft-trim " << insertion << std::endl;
if (insertion.y2 > h) {
if (insertion.y2 == h_physical) {
} else if (insertion.y2 < h_physical) {
@@ -1390,7 +1390,7 @@ void BranchingScheme::update(
}

// Increase height if too close from border
//std::cout << "update y border " << insertion << std::endl;
//std::cout << "- update y border " << insertion << std::endl;
if (insertion.y2 < h_physical
&& min_waste > 0
&& insertion.y2 + cut_thickness + min_waste > h_physical) {
@@ -1438,7 +1438,7 @@ void BranchingScheme::update(
}

// Check max height
//std::cout << "update y max " << insertion << std::endl;
//std::cout << "- update y max " << insertion << std::endl;
if (insertion.y2 > insertion.y2_max) {
return;
}
@@ -1596,9 +1596,6 @@ Solution BranchingScheme::to_solution(

const Node* current_node = descendents[node_pos];
//std::cout << *current_node << std::endl;
BinPos i = current_node->number_of_bins - 1;
BinTypeId bin_type_id = instance().bin_type_id(i);
const BinType& bin_type = instance().bin_type(bin_type_id);
bool has_item = (current_node->item_type_id_1 != -1 || current_node->item_type_id_2 != -1);
Depth df_next = (node_pos < (SolutionNodeId)descendents.size() - 1)?
descendents[node_pos + 1]->df: -1;
@@ -1609,12 +1606,18 @@ Solution BranchingScheme::to_solution(
(instance().parameters().number_of_stages == 3 && current_node->first_stage_orientation == CutOrientation::Vertical)
|| (instance().parameters().number_of_stages == 2 && current_node->first_stage_orientation == CutOrientation::Horizontal))?
CutOrientation::Vertical: CutOrientation::Horizontal;
BinTypeId bin_type_id = instance().bin_type_id(number_of_bins);
number_of_bins++;
BinTypeId bin_type_id = instance().bin_type_id(number_of_bins - 1);
solution_builder.add_bin(
bin_type_id,
1,
cut_orientation);
number_of_bins++;

const BinType& bin_type = instance().bin_type(bin_type_id);
if (bin_type.left_trim_type == TrimType::Soft
&& bin_type.left_trim > 0) {
solution_builder.add_node(1, bin_type.left_trim);
}
}

// Create a new first-level sub-plate.
@@ -1630,6 +1633,13 @@ Solution BranchingScheme::to_solution(
subplate1_curr_x1 = descendents[node_pos_2]->x1_curr;
}
solution_builder.add_node(1, subplate1_curr_x1);

BinTypeId bin_type_id = instance().bin_type_id(number_of_bins - 1);
const BinType& bin_type = instance().bin_type(bin_type_id);
if (bin_type.bottom_trim_type == TrimType::Soft
&& bin_type.bottom_trim > 0) {
solution_builder.add_node(2, bin_type.bottom_trim);
}
}
}

2 changes: 1 addition & 1 deletion src/rectangleguillotine/instance.cpp
Original file line number Diff line number Diff line change
@@ -51,7 +51,7 @@ std::istream& packingsolver::rectangleguillotine::operator>>(
{
std::string token;
in >> token;
if (token == "s" || token == "H" || token == "hard" || token == "Hard" || token == "0") {
if (token == "h" || token == "H" || token == "hard" || token == "Hard" || token == "0") {
trim_type = TrimType::Hard;
} else if (token == "s" || token == "S" || token == "soft" || token == "Soft" || token == "1") {
trim_type = TrimType::Soft;
12 changes: 6 additions & 6 deletions src/rectangleguillotine/solution_builder.cpp
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ void SolutionBuilder::add_bin(
node.l = 0;
node.r = bin_type.left_trim;
node.b = (!bottom_trim)? 0: bin_type.bottom_trim;
node.t = bin_type.rect.h - ((!top_trim)? 0: bin_type.top_trim);
node.t = (!top_trim)? bin_type.rect.h: bin_type.rect.h - bin_type.top_trim;
node.item_type_id = -1;
root.children.push_back(bin.nodes.size());
bin.nodes.push_back(node);
@@ -117,7 +117,7 @@ void SolutionBuilder::add_bin(
node.d = -1;
node.f = 0;
node.l = (!left_trim)? 0: bin_type.left_trim;
node.r = bin_type.rect.w - ((!right_trim)? 0: bin_type.right_trim);
node.r = (!right_trim)? bin_type.rect.w: bin_type.rect.w - bin_type.right_trim;
node.b = 0;
node.t = bin_type.bottom_trim;
node.item_type_id = -1;
@@ -132,7 +132,7 @@ void SolutionBuilder::add_bin(
node.l = bin_type.rect.w - bin_type.right_trim;
node.r = bin_type.rect.w;
node.b = (!bottom_trim)? 0: bin_type.bottom_trim;
node.t = bin_type.rect.h - ((!top_trim)? 0: bin_type.top_trim);
node.t = (!top_trim)? bin_type.rect.h: bin_type.rect.h - bin_type.top_trim;
node.item_type_id = -1;
root.children.push_back(bin.nodes.size());
bin.nodes.push_back(node);
@@ -143,7 +143,7 @@ void SolutionBuilder::add_bin(
node.d = -1;
node.f = 0;
node.l = (!left_trim)? 0: bin_type.left_trim;
node.r = bin_type.rect.w - ((!right_trim)? 0: bin_type.right_trim);
node.r = (!right_trim)? bin_type.rect.w: bin_type.rect.w - bin_type.right_trim;
node.b = bin_type.rect.h - bin_type.top_trim;
node.t = bin_type.rect.h;
node.item_type_id = -1;
@@ -155,9 +155,9 @@ void SolutionBuilder::add_bin(
node.d = 0;
node.f = 0;
node.l = (!left_trim)? 0: bin_type.left_trim;
node.r = bin_type.rect.w - ((!right_trim)? 0: bin_type.right_trim);
node.r = (!right_trim)? bin_type.rect.w: bin_type.rect.w - bin_type.right_trim;
node.b = (!bottom_trim)? 0: bin_type.bottom_trim;
node.t = bin_type.rect.h - ((!top_trim)? 0: bin_type.top_trim);
node.t = (!top_trim)? bin_type.rect.h: bin_type.rect.h - bin_type.top_trim;
node.item_type_id = -1;
root.children.push_back(bin.nodes.size());
bin.nodes.push_back(node);
Original file line number Diff line number Diff line change
@@ -117,6 +117,12 @@ INSTANTIATE_TEST_SUITE_P(
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_soft_trims_3evo" / "items.csv",
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_soft_trims_3evo" / "parameters.csv",
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_soft_trims_3evo" / "solution.csv",
}, {
fs::path("data") / "rectangleguillotine" / "users" / "2025-03-04" / "bins.csv",
fs::path(""),
fs::path("data") / "rectangleguillotine" / "users" / "2025-03-04" / "items.csv",
fs::path("data") / "rectangleguillotine" / "users" / "2025-03-04" / "parameters.csv",
fs::path("data") / "rectangleguillotine" / "users" / "2025-03-04" / "solution.csv",
}}));


Loading