Skip to content
Merged
Show file tree
Hide file tree
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
4,012 changes: 2,006 additions & 2,006 deletions data/irregular/users/2025-01-12_solution.json

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions include/packingsolver/irregular/instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,11 @@ struct BinType
/** Scaled area of the bin type. */
AreaDbl area_scaled = 0.0;

/** Bounding box of the bin type. */
AxisAlignedBoundingBox aabb;
/** Bounding box of the original bin type. */
AxisAlignedBoundingBox aabb_orig;

/** Bounding box of the scaled bin type. */
AxisAlignedBoundingBox aabb_scaled;


AreaDbl space() const { return area_orig; }
Expand Down Expand Up @@ -351,6 +354,28 @@ class Instance
/** Get an item type. */
inline const ItemType& item_type(ItemTypeId item_type_id) const { return item_types_[item_type_id]; }

/**
* Return the scaled shape of item type 'item_type_id', shape 'item_shape_pos',
* after applying the given mirror (axial symmetry about the y-axis) and
* rotation angle.
*/
ShapeWithHoles item_shape_scaled(
ItemTypeId item_type_id,
ItemPos item_shape_pos,
Angle angle,
bool mirror) const;

/**
* Return the original (unscaled) shape of item type 'item_type_id', shape
* 'item_shape_pos', after applying the given mirror (axial symmetry about
* the y-axis) and rotation angle.
*/
ShapeWithHoles item_shape_orig(
ItemTypeId item_type_id,
ItemPos item_shape_pos,
Angle angle,
bool mirror) const;

/** Get the number of items. */
inline ItemPos number_of_items() const { return number_of_items_; }

Expand Down
13 changes: 9 additions & 4 deletions include/packingsolver/irregular/solution.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,12 @@ class Solution
inline LengthDbl y_max() const { return y_max_; }

/** Get the area of the (last bin of the) solution. */
AreaDbl open_dimension_xy_areaarea() const;
AreaDbl open_dimension_xy_area() const;

/** Get the area of the solution. */
inline Profit leftover_value() const { return leftover_value_; }
inline Profit leftover_value_orig() const { return leftover_value_orig_; }

inline Profit leftover_value_scaled() const { return leftover_value_scaled_; }

/** Get the waste of the solution including the residual. */
inline AreaDbl full_waste() const { return bin_area() - item_area(); }
Expand Down Expand Up @@ -256,8 +258,11 @@ class Solution
/** Number of items. */
ItemPos number_of_items_ = 0;

/** Value of the leftover. */
Profit leftover_value_ = 0.0;
/** Value of the leftover in original coordinates. */
Profit leftover_value_orig_ = 0.0;

/** Value of the leftover in scaled coordinates. */
Profit leftover_value_scaled_ = 0.0;

/** Total area of the bins of the solution. */
AreaDbl bin_area_ = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/box/algorithm_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void AlgorithmFormatter::print_header()
<< std::setw(32) << "Comment"
<< std::endl
<< std::setw(12) << "----"
<< std::setw(12) << "-----"
<< std::setw(12) << "-"
<< std::setw(32) << "-------"
<< std::endl;
break;
Expand All @@ -91,7 +91,7 @@ void AlgorithmFormatter::print_header()
<< std::setw(32) << "Comment"
<< std::endl
<< std::setw(12) << "----"
<< std::setw(12) << "-----"
<< std::setw(12) << "-"
<< std::setw(32) << "-------"
<< std::endl;
break;
Expand Down
4 changes: 2 additions & 2 deletions src/irregular/algorithm_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void AlgorithmFormatter::print(
*os_
<< std::setw(12) << std::fixed << std::setprecision(3) << output_.time << std::defaultfloat << std::setprecision(precision)
<< std::setw(12) << output_.solution_pool.best().number_of_bins()
<< std::setw(12) << output_.solution_pool.best().leftover_value()
<< std::setw(12) << output_.solution_pool.best().leftover_value_orig()
<< std::setw(32) << s
<< std::endl;
break;
Expand All @@ -202,7 +202,7 @@ void AlgorithmFormatter::print(
} case Objective::OpenDimensionXY: {
*os_
<< std::setw(12) << std::fixed << std::setprecision(3) << output_.time << std::defaultfloat << std::setprecision(precision)
<< std::setw(12) << output_.solution_pool.best().open_dimension_xy_areaarea()
<< std::setw(12) << output_.solution_pool.best().open_dimension_xy_area()
<< std::setw(12) << output_.solution_pool.best().x_max()
<< std::setw(12) << output_.solution_pool.best().y_max()
<< std::setw(32) << s
Expand Down
18 changes: 9 additions & 9 deletions src/irregular/branching_scheme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ BranchingScheme::Direction default_direction(
BinTypeId bin_type_id)
{
const BinType& bin_type = instance.bin_type(bin_type_id);
bool lengthwise = (bin_type.aabb.x_max - bin_type.aabb.x_min) >= (bin_type.aabb.y_max - bin_type.aabb.y_min);
bool lengthwise = (bin_type.aabb_scaled.x_max - bin_type.aabb_scaled.x_min) >= (bin_type.aabb_scaled.y_max - bin_type.aabb_scaled.y_min);
switch (instance.parameters().leftover_corner) {
case Corner::BottomLeft: {
return (lengthwise)?
Expand Down Expand Up @@ -1256,20 +1256,20 @@ BranchingScheme::Node BranchingScheme::child_tmp(

switch (instance().parameters().leftover_corner) {
case Corner::BottomLeft: {
node.leftover_value = (bin_type.aabb.x_max - bin_type.aabb.x_min) * (bin_type.aabb.y_max - bin_type.aabb.y_min)
- (node.x_max - bin_type.aabb.x_min) * (node.y_max - bin_type.aabb.y_min);
node.leftover_value = (bin_type.aabb_orig.x_max - bin_type.aabb_orig.x_min) * (bin_type.aabb_orig.y_max - bin_type.aabb_orig.y_min)
- (node.x_max - bin_type.aabb_orig.x_min) * (node.y_max - bin_type.aabb_orig.y_min);
break;
} case Corner::BottomRight: {
node.leftover_value = (bin_type.aabb.x_max - bin_type.aabb.x_min) * (bin_type.aabb.y_max - bin_type.aabb.y_min)
- (bin_type.aabb.x_max - node.x_min) * (node.y_max - bin_type.aabb.y_min);
node.leftover_value = (bin_type.aabb_orig.x_max - bin_type.aabb_orig.x_min) * (bin_type.aabb_orig.y_max - bin_type.aabb_orig.y_min)
- (bin_type.aabb_orig.x_max - node.x_min) * (node.y_max - bin_type.aabb_orig.y_min);
break;
} case Corner::TopLeft: {
node.leftover_value = (bin_type.aabb.x_max - bin_type.aabb.x_min) * (bin_type.aabb.y_max - bin_type.aabb.y_min)
- (node.x_max - bin_type.aabb.x_min) * (bin_type.aabb.y_max - node.y_min);
node.leftover_value = (bin_type.aabb_orig.x_max - bin_type.aabb_orig.x_min) * (bin_type.aabb_orig.y_max - bin_type.aabb_orig.y_min)
- (node.x_max - bin_type.aabb_orig.x_min) * (bin_type.aabb_orig.y_max - node.y_min);
break;
} case Corner::TopRight: {
node.leftover_value = (bin_type.aabb.x_max - bin_type.aabb.x_min) * (bin_type.aabb.y_max - bin_type.aabb.y_min)
- (bin_type.aabb.x_max - node.x_min) * (bin_type.aabb.y_max - node.y_min);
node.leftover_value = (bin_type.aabb_orig.x_max - bin_type.aabb_orig.x_min) * (bin_type.aabb_orig.y_max - bin_type.aabb_orig.y_min)
- (bin_type.aabb_orig.x_max - node.x_min) * (bin_type.aabb_orig.y_max - node.y_min);
break;
}
}
Expand Down
32 changes: 28 additions & 4 deletions src/irregular/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,12 @@ void BinType::write_svg(
"unable to open file \"" + file_path + "\".");
}

LengthDbl width = (aabb.x_max - aabb.x_min);
LengthDbl height = (aabb.y_max - aabb.y_min);
LengthDbl width = (aabb_orig.x_max - aabb_orig.x_min);
LengthDbl height = (aabb_orig.y_max - aabb_orig.y_min);

std::string s = "<svg viewBox=\""
+ std::to_string(aabb.x_min)
+ " " + std::to_string(-aabb.y_min - height)
+ std::to_string(aabb_orig.x_min)
+ " " + std::to_string(-aabb_orig.y_min - height)
+ " " + std::to_string(width)
+ " " + std::to_string(height)
+ "\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
Expand Down Expand Up @@ -308,6 +308,30 @@ void BinType::write_svg(
/////////////////////////////////// Instance ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

ShapeWithHoles Instance::item_shape_scaled(
ItemTypeId item_type_id,
ItemPos item_shape_pos,
Angle angle,
bool mirror) const
{
ShapeWithHoles shape = item_types_[item_type_id].shapes[item_shape_pos].shape_scaled;
if (mirror)
shape = shape.axial_symmetry_y_axis();
return shape.rotate(angle);
}

ShapeWithHoles Instance::item_shape_orig(
ItemTypeId item_type_id,
ItemPos item_shape_pos,
Angle angle,
bool mirror) const
{
ShapeWithHoles shape = item_types_[item_type_id].shapes[item_shape_pos].shape_orig;
if (mirror)
shape = shape.axial_symmetry_y_axis();
return shape.rotate(angle);
}

bool Instance::can_contain(
QualityRule quality_rule,
DefectTypeId type) const
Expand Down
3 changes: 2 additions & 1 deletion src/irregular/instance_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ BinTypeId InstanceBuilder::add_bin_type(
BinType bin_type;
bin_type.shape_orig = shape;
bin_type.area_orig = shape.compute_area();
bin_type.aabb = shape.compute_min_max();
bin_type.aabb_orig = shape.compute_min_max();
bin_type.cost = (cost == -1)? bin_type.area_orig: cost;
bin_type.copies = copies;
bin_type.copies_min = copies_min;
Expand Down Expand Up @@ -684,6 +684,7 @@ Instance InstanceBuilder::build()
defect.shape_scaled = instance_.parameters().scale_value * defect.shape_orig;
}
bin_type.area_scaled = bin_type.shape_scaled.compute_area();
bin_type.aabb_scaled = bin_type.shape_scaled.compute_min_max();

// Compute inflated defects.
for (Defect& defect: bin_type.defects) {
Expand Down
16 changes: 8 additions & 8 deletions src/irregular/linear_programming.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,10 +326,10 @@ Solution linear_programming_anchor(
item_var_pos < (ItemPos)unfixed_items.size();
++item_var_pos) {
const AxisAlignedBoundingBox& ia = unfixed_item_aabbs[item_var_pos].item_aabb;
LengthDbl x_min = (x_weight < 0)? solution.x_min(): bin_type.aabb.x_min;
LengthDbl x_max = (x_weight > 0)? solution.x_max(): bin_type.aabb.x_max;
LengthDbl y_min = (y_weight < 0)? solution.y_min(): bin_type.aabb.y_min;
LengthDbl y_max = (y_weight > 0)? solution.y_max(): bin_type.aabb.y_max;
LengthDbl x_min = (x_weight < 0)? solution.x_min(): bin_type.aabb_scaled.x_min;
LengthDbl x_max = (x_weight > 0)? solution.x_max(): bin_type.aabb_scaled.x_max;
LengthDbl y_min = (y_weight < 0)? solution.y_min(): bin_type.aabb_scaled.y_min;
LengthDbl y_max = (y_weight > 0)? solution.y_max(): bin_type.aabb_scaled.y_max;
item_bin_bounds[item_var_pos].x_min = x_min * instance.parameters().scale_value - ia.x_min;
item_bin_bounds[item_var_pos].x_max = x_max * instance.parameters().scale_value - ia.x_max;
item_bin_bounds[item_var_pos].y_min = y_min * instance.parameters().scale_value - ia.y_min;
Expand Down Expand Up @@ -847,10 +847,10 @@ LinearProgrammingMinimizeShrinkageOutput packingsolver::irregular::linear_progra
unfixed_item_aabbs[item_var_pos].part_movement_aabbs[shape_pos][part_pos];

// RHS: part movement AABB clamped to bin bounds.
const LengthDbl x_min = (std::max)(pm.x_min, bin_type.aabb.x_min * sv);
const LengthDbl x_max = (std::min)(pm.x_max, bin_type.aabb.x_max * sv);
const LengthDbl y_min = (std::max)(pm.y_min, bin_type.aabb.y_min * sv);
const LengthDbl y_max = (std::min)(pm.y_max, bin_type.aabb.y_max * sv);
const LengthDbl x_min = (std::max)(pm.x_min, bin_type.aabb_scaled.x_min * sv);
const LengthDbl x_max = (std::min)(pm.x_max, bin_type.aabb_scaled.x_max * sv);
const LengthDbl y_min = (std::max)(pm.y_min, bin_type.aabb_scaled.y_min * sv);
const LengthDbl y_max = (std::min)(pm.y_max, bin_type.aabb_scaled.y_max * sv);

const std::string sid = std::to_string(item_pos)
+ "_s" + std::to_string(shape_pos)
Expand Down
6 changes: 3 additions & 3 deletions src/irregular/local_search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ BinPos assign_item_to_bin(
++bin_pos) {
const BinTypeId bin_type_id = solution.bin(bin_pos).bin_type_id;
const BinType& bin_type = instance.bin_type(bin_type_id);
if (bin_type.aabb.x_max - bin_type.aabb.x_min < item_aabb.x_max - item_aabb.x_min
|| bin_type.aabb.y_max - bin_type.aabb.y_min < item_aabb.y_max - item_aabb.y_min)
if (bin_type.aabb_orig.x_max - bin_type.aabb_orig.x_min < item_aabb.x_max - item_aabb.x_min
|| bin_type.aabb_orig.y_max - bin_type.aabb_orig.y_min < item_aabb.y_max - item_aabb.y_min)
continue;
if (bin_data[bin_pos].remaining_area > best_remaining) {
best_remaining = bin_data[bin_pos].remaining_area;
Expand All @@ -87,7 +87,7 @@ BinPos assign_item_to_bin(
// bin AABB and the shapes of existing items, defects, and borders.
const BinTypeId best_bin_type_id = solution.bin(best_bin_pos).bin_type_id;
const BinType& best_bin_type = instance.bin_type(best_bin_type_id);
const AxisAlignedBoundingBox& bin_aabb = best_bin_type.aabb;
const AxisAlignedBoundingBox& bin_aabb = best_bin_type.aabb_orig;

shape::ShapeWithHoles bin_shape{instance.parameters().scale_value * shape::build_rectangle(bin_aabb), {}};

Expand Down
42 changes: 14 additions & 28 deletions src/irregular/milp_raster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,17 @@ Solution solve_milp_raster_for_cell_size(
const BinType& bin_type = instance.bin_type(bin_type_id);
BinTypeData& data = bin_type_data[bin_type_id];

LengthDbl x_min_scaled = bin_type.aabb.x_min * scale;
LengthDbl x_max_scaled = bin_type.aabb.x_max * scale;
LengthDbl y_min_scaled = bin_type.aabb.y_min * scale;
LengthDbl y_max_scaled = bin_type.aabb.y_max * scale;

data.col_shift = (shape::ColumnId)std::floor(x_min_scaled / cell_size);
if (shape::strictly_greater(x_min_scaled, data.col_shift * cell_size))
data.col_shift = (shape::ColumnId)std::floor(bin_type.aabb_scaled.x_min / cell_size);
if (shape::strictly_greater(bin_type.aabb_scaled.x_min, data.col_shift * cell_size))
data.col_shift++;
data.col_max = (shape::ColumnId)std::floor(x_max_scaled / cell_size);
if (shape::strictly_lesser(x_max_scaled, (data.col_max + 1) * cell_size))
data.col_max = (shape::ColumnId)std::floor(bin_type.aabb_scaled.x_max / cell_size);
if (shape::strictly_lesser(bin_type.aabb_scaled.x_max, (data.col_max + 1) * cell_size))
data.col_max--;
data.row_shift = (shape::RowId)std::floor(y_min_scaled / cell_size);
if (shape::strictly_greater(y_min_scaled, data.row_shift * cell_size))
data.row_shift = (shape::RowId)std::floor(bin_type.aabb_scaled.y_min / cell_size);
if (shape::strictly_greater(bin_type.aabb_scaled.y_min, data.row_shift * cell_size))
data.row_shift++;
data.row_max = (shape::RowId)std::floor(y_max_scaled / cell_size);
if (shape::strictly_lesser(y_max_scaled, (data.row_max + 1) * cell_size))
data.row_max = (shape::RowId)std::floor(bin_type.aabb_scaled.y_max / cell_size);
if (shape::strictly_lesser(bin_type.aabb_scaled.y_max, (data.row_max + 1) * cell_size))
data.row_max--;
data.num_cols = data.col_max - data.col_shift + 1;
data.num_rows = data.row_max - data.row_shift + 1;
Expand Down Expand Up @@ -151,11 +146,7 @@ Solution solve_milp_raster_for_cell_size(
for (ItemShapePos item_shape_pos = 0;
item_shape_pos < (ItemShapePos)item_type.shapes.size();
++item_shape_pos) {
const ItemShape& item_shape = item_type.shapes[item_shape_pos];
ShapeWithHoles transformed = fixed_item.mirror?
item_shape.shape_scaled.axial_symmetry_y_axis():
item_shape.shape_scaled;
transformed = transformed.rotate(fixed_item.angle);
ShapeWithHoles transformed = instance.item_shape_scaled(fixed_item.item_type_id, item_shape_pos, fixed_item.angle, fixed_item.mirror);
transformed.shift(
fixed_item.bl_corner.x * scale,
fixed_item.bl_corner.y * scale);
Expand Down Expand Up @@ -183,11 +174,10 @@ Solution solve_milp_raster_for_cell_size(
// Compute AABB of all item shapes after applying mirror then
// rotation, matching the order used in convert_shape.
AxisAlignedBoundingBox combined_aabb;
for (const ItemShape& item_shape: item_type.shapes) {
ShapeWithHoles transformed = rotation.mirror?
item_shape.shape_scaled.axial_symmetry_y_axis():
item_shape.shape_scaled;
transformed = transformed.rotate(rotation.angle);
for (ItemShapePos item_shape_pos = 0;
item_shape_pos < (ItemShapePos)item_type.shapes.size();
++item_shape_pos) {
ShapeWithHoles transformed = instance.item_shape_scaled(item_type_id, item_shape_pos, rotation.angle, rotation.mirror);
AxisAlignedBoundingBox shape_aabb = transformed.compute_min_max();
combined_aabb = merge(combined_aabb, shape_aabb);
}
Expand All @@ -197,11 +187,7 @@ Solution solve_milp_raster_for_cell_size(
for (ItemShapePos item_shape_pos = 0;
item_shape_pos < (ItemShapePos)item_type.shapes.size();
++item_shape_pos) {
const ItemShape& item_shape = item_type.shapes[item_shape_pos];
ShapeWithHoles transformed = (rotation.mirror)?
item_shape.shape_scaled.axial_symmetry_y_axis():
item_shape.shape_scaled;
transformed = transformed.rotate(rotation.angle);
ShapeWithHoles transformed = instance.item_shape_scaled(item_type_id, item_shape_pos, rotation.angle, rotation.mirror);
transformed.shift(-combined_aabb.x_min, -combined_aabb.y_min);
std::vector<shape::IntersectedCell> raster_cells = shape::rasterization(transformed, cell_size, cell_size);
for (const shape::IntersectedCell& ic: raster_cells)
Expand Down
8 changes: 4 additions & 4 deletions src/irregular/post_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ static Solution compute_shifted_solution(
LengthDbl dx = 0.0;
LengthDbl dy = 0.0;
if (x_weight > 0) {
dx = bin_type.aabb.x_min - solution_bin.x_min;
dx = bin_type.aabb_scaled.x_min - solution_bin.x_min;
} else if (x_weight < 0) {
dx = bin_type.aabb.x_max - solution_bin.x_max;
dx = bin_type.aabb_scaled.x_max - solution_bin.x_max;
}
if (y_weight > 0) {
dy = bin_type.aabb.y_min - solution_bin.y_min;
dy = bin_type.aabb_scaled.y_min - solution_bin.y_min;
} else if (y_weight < 0) {
dy = bin_type.aabb.y_max - solution_bin.y_max;
dy = bin_type.aabb_scaled.y_max - solution_bin.y_max;
}
//std::cout << "dx " << dx << " dy " << dy << std::endl;

Expand Down
Loading
Loading