diff --git a/data/rectangleguillotine/users/2025-03-04/bins.csv b/data/rectangleguillotine/users/2025-03-04/bins.csv new file mode 100644 index 00000000..3dac8788 --- /dev/null +++ b/data/rectangleguillotine/users/2025-03-04/bins.csv @@ -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 diff --git a/data/rectangleguillotine/users/2025-03-04/items.csv b/data/rectangleguillotine/users/2025-03-04/items.csv new file mode 100644 index 00000000..a22b60b6 --- /dev/null +++ b/data/rectangleguillotine/users/2025-03-04/items.csv @@ -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 diff --git a/data/rectangleguillotine/users/2025-03-04/parameters.csv b/data/rectangleguillotine/users/2025-03-04/parameters.csv new file mode 100644 index 00000000..9300de7e --- /dev/null +++ b/data/rectangleguillotine/users/2025-03-04/parameters.csv @@ -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 diff --git a/data/rectangleguillotine/users/2025-03-04/solution.csv b/data/rectangleguillotine/users/2025-03-04/solution.csv new file mode 100644 index 00000000..670ad7fe --- /dev/null +++ b/data/rectangleguillotine/users/2025-03-04/solution.csv @@ -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 diff --git a/src/rectangleguillotine/branching_scheme.cpp b/src/rectangleguillotine/branching_scheme.cpp index e11f77c2..f8e759ba 100644 --- a/src/rectangleguillotine/branching_scheme.cpp +++ b/src/rectangleguillotine/branching_scheme.cpp @@ -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); + } } } diff --git a/src/rectangleguillotine/instance.cpp b/src/rectangleguillotine/instance.cpp index b0ff7228..1a4a7f7a 100644 --- a/src/rectangleguillotine/instance.cpp +++ b/src/rectangleguillotine/instance.cpp @@ -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; diff --git a/src/rectangleguillotine/solution_builder.cpp b/src/rectangleguillotine/solution_builder.cpp index 313c0855..322b8f40 100644 --- a/src/rectangleguillotine/solution_builder.cpp +++ b/src/rectangleguillotine/solution_builder.cpp @@ -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); diff --git a/test/rectangleguillotine/branching_scheme/branching_scheme_test.cpp b/test/rectangleguillotine/branching_scheme/branching_scheme_test.cpp index fa5e0f8c..c203a864 100644 --- a/test/rectangleguillotine/branching_scheme/branching_scheme_test.cpp +++ b/test/rectangleguillotine/branching_scheme/branching_scheme_test.cpp @@ -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", }}));