Skip to content

Commit

Permalink
Implement trims with column-generation-2 algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
fontanf committed Jan 4, 2025
1 parent f295ded commit d83a02b
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 21 deletions.
2 changes: 2 additions & 0 deletions data/rectangleguillotine/tests/knapsack_trims_bins.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
WIDTH,HEIGHT,LEFT_TRIM,RIGHT_TRIM,BOTTOM_TRIM,TOP_TRIM
20,15,2,3,2,3
5 changes: 5 additions & 0 deletions data/rectangleguillotine/tests/knapsack_trims_items.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
WIDTH,HEIGHT,ORIENTED
10,6,1
9,4,1
5,7,2
4,3,2
5 changes: 5 additions & 0 deletions data/rectangleguillotine/tests/knapsack_trims_parameters.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
NAME,VALUE
objective,knapsack
number_of_stages,2
cut_type,non-exact
first_stage_orientation,vertical
23 changes: 23 additions & 0 deletions data/rectangleguillotine/tests/knapsack_trims_solution.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
PLATE_ID,NODE_ID,X,Y,WIDTH,HEIGHT,TYPE,CUT,PARENT
0,0,0,0,20,15,0,0,
0,1,0,0,2,2,-1,-1,0
0,2,0,12,2,3,-1,-1,0
0,3,17,0,3,2,-1,-1,0
0,4,17,12,3,3,-1,-1,0
0,5,0,2,2,10,-1,-1,0
0,6,2,0,15,2,-1,-1,0
0,7,17,2,3,10,-1,-1,0
0,8,2,12,15,3,-1,-1,0
0,9,2,2,15,10,-2,0,0
0,10,2,2,5,10,-2,1,9
0,11,2,2,5,7,-2,2,10
0,12,2,2,5,7,2,3,11
0,13,2,9,5,3,-2,2,10
0,14,2,9,4,3,3,3,13
0,15,6,9,1,3,-1,3,13
0,16,7,2,10,10,-2,1,9
0,17,7,2,10,6,-2,2,16
0,18,7,2,10,6,0,3,17
0,19,7,8,10,4,-2,2,16
0,20,7,8,9,4,1,3,19
0,21,16,8,1,4,-1,3,19
38 changes: 22 additions & 16 deletions src/rectangleguillotine/column_generation_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class ColumnGenerationPricingSolver: public columngenerationsolver::PricingSolve
columngenerationsolver::Model get_model(
const Instance& instance)
{
const BinType& bin_type = instance.bin_type(0);

columngenerationsolver::Model model;

Profit maximum_bin_type_cost = 0;
Expand Down Expand Up @@ -99,7 +101,7 @@ columngenerationsolver::Model get_model(

columngenerationsolver::Row row;
row.lower_bound = 0;
row.upper_bound = instance.bin_type(0).rect.w;
row.upper_bound = bin_type.rect.w - bin_type.left_trim - bin_type.right_trim;
row.coefficient_lower_bound = 0;
row.coefficient_upper_bound = 1;
model.rows.push_back(row);
Expand Down Expand Up @@ -150,13 +152,16 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(
const std::vector<Value>& duals)
{
//std::cout << "solve_pricing" << std::endl;

const BinType& bin_type = instance_.bin_type(0);

PricingOutput output;
Value reduced_cost_bound = 0.0;

// Generate one-staged exact patterns.
{
Length width = instance_.bin_type(0).rect.w - filled_width_;
Length height = instance_.bin_type(0).rect.h;
Length width = bin_type.rect.w - bin_type.left_trim - bin_type.right_trim - filled_width_;
Length height = bin_type.rect.h - bin_type.bottom_trim - bin_type.top_trim;
for (;;) {

// Build one-dimensional knapsack instance.
Expand Down Expand Up @@ -211,8 +216,8 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(
Column column;
SolutionBuilder extra_solution_builder(instance_);
extra_solution_builder.add_bin(0, 1, CutOrientation::Vertical);
extra_solution_builder.add_node(1, width);
Length cut_position = 0;
extra_solution_builder.add_node(1, bin_type.left_trim + width);
Length cut_position = bin_type.bottom_trim;
for (ItemTypeId kp_item_type_id = 0;
kp_item_type_id < kp_instance.number_of_item_types();
++kp_item_type_id) {
Expand Down Expand Up @@ -295,8 +300,8 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(

// Generate one-staged non-exact patterns.
{
Length width = instance_.bin_type(0).rect.w - filled_width_;
Length height = instance_.bin_type(0).rect.h;
Length width = bin_type.rect.w - bin_type.left_trim - bin_type.right_trim - filled_width_;
Length height = bin_type.rect.h - bin_type.bottom_trim - bin_type.top_trim;
for (;;) {

// Build one-dimensional knapsack instance.
Expand Down Expand Up @@ -389,8 +394,8 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(
// Build extra solution.
SolutionBuilder extra_solution_builder(instance_);
extra_solution_builder.add_bin(0, 1, CutOrientation::Vertical);
extra_solution_builder.add_node(1, width_max);
Length cut_position = 0;
extra_solution_builder.add_node(1, bin_type.left_trim + width_max);
Length cut_position = bin_type.bottom_trim;
for (ItemTypeId kp_item_type_id = 0;
kp_item_type_id < kp_instance.number_of_item_types();
++kp_item_type_id) {
Expand All @@ -406,7 +411,7 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(
cut_position += kp_instance.item_type(kp_item_type_id).length;
extra_solution_builder.add_node(2, cut_position);
if (width_cur < width_max)
extra_solution_builder.add_node(3, width_cur);
extra_solution_builder.add_node(3, bin_type.left_trim + width_cur);
extra_solution_builder.set_last_node_item(item_type_id);
}
}
Expand Down Expand Up @@ -459,8 +464,8 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(

// Generate two-staged homogenous patterns.
{
Length width = instance_.bin_type(0).rect.w - filled_width_;
Length height = instance_.bin_type(0).rect.h;
Length width = bin_type.rect.w - bin_type.left_trim - bin_type.right_trim - filled_width_;
Length height = bin_type.rect.h - bin_type.bottom_trim - bin_type.top_trim;
// TODO
}
if (instance_.parameters().number_of_stages == 3
Expand All @@ -469,8 +474,8 @@ PricingOutput ColumnGenerationPricingSolver::solve_pricing(

// Generate other patterns.
{
Length width = instance_.bin_type(0).rect.w - filled_width_;
Length height = instance_.bin_type(0).rect.h;
Length width = bin_type.rect.w - bin_type.left_trim - bin_type.right_trim - filled_width_;
Length height = bin_type.rect.h - bin_type.bottom_trim - bin_type.top_trim;
// TODO
}

Expand Down Expand Up @@ -511,6 +516,7 @@ void column_generation_2_vertical(
cgslds_parameters.new_solution_callback = [&instance, &algorithm_formatter](
const columngenerationsolver::Output& cgs_output)
{
const BinType& bin_type = instance.bin_type(0);
const columngenerationsolver::LimitedDiscrepancySearchOutput& cgslds_output
= static_cast<const columngenerationsolver::LimitedDiscrepancySearchOutput&>(cgs_output);
if (cgslds_output.solution.feasible()) {
Expand All @@ -525,7 +531,7 @@ void column_generation_2_vertical(
bool first = true;
Length offset_new = offset;
for (const SolutionNode& node: bin.nodes) {
if (node.d == 0)
if (node.d <= 0)
continue;
if (node.d == 1) {
if (!first)
Expand Down Expand Up @@ -634,7 +640,7 @@ void column_generation_2_horizontal(
flipped_bin.copies,
CutOrientation::Horizontal);
for (const SolutionNode& flipped_node: flipped_bin.nodes) {
if (flipped_node.d == 0)
if (flipped_node.d <= 0)
continue;
if (flipped_node.d % 2 == 1) {
solution_builder.add_node(flipped_node.d, flipped_node.r);
Expand Down
18 changes: 13 additions & 5 deletions src/rectangleguillotine/solution_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,15 @@ void SolutionBuilder::set_last_node_item(
if (!ok) {
throw std::logic_error(
"rectangleguillotine::SolutionBuilder::set_last_node_item: "
"wrong item dimensions.");
"wrong item dimensions"
"; item_type_id: " + std::to_string(item_type_id)
+ "; item_type.rect.w: " + std::to_string(item_type.rect.w)
+ "; item_type.rect.h: " + std::to_string(item_type.rect.h)
+ "; node.l: " + std::to_string(node.l)
+ "; node.r: " + std::to_string(node.r)
+ "; node.b: " + std::to_string(node.b)
+ "; node.t: " + std::to_string(node.t)
+ ".");
}

node.item_type_id = item_type_id;
Expand Down Expand Up @@ -407,16 +415,16 @@ void SolutionBuilder::read(
break;
}
}
std::cout << "bin_type_id " << bin_type_id << std::endl;
std::cout << "first_cut_orientation " << first_cut_orientation << std::endl;
//std::cout << "bin_type_id " << bin_type_id << std::endl;
//std::cout << "first_cut_orientation " << first_cut_orientation << std::endl;
add_bin(bin_type_id, 1, first_cut_orientation);

for (SolutionNodeId node_id = 0;
node_id < (SolutionNodeId)nodes[bin_pos].size();
++node_id) {
const SolutionNode& node = nodes[bin_pos][node_id];
std::cout << node << std::endl;
if (node.d == 0)
//std::cout << node << std::endl;
if (node.d <= 0)
continue;
if ((first_cut_orientation == CutOrientation::Vertical
&& node.d % 2 == 1)
Expand Down
6 changes: 6 additions & 0 deletions test/rectangleguillotine/column_generation_2_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ INSTANTIATE_TEST_SUITE_P(
fs::path(""),
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_horizontal_parameters.csv",
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_horizontal_solution.csv",
}, {
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_trims_items.csv",
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_trims_bins.csv",
fs::path(""),
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_trims_parameters.csv",
fs::path("data") / "rectangleguillotine" / "tests" / "knapsack_trims_solution.csv",
}}));

0 comments on commit d83a02b

Please sign in to comment.