Partitioning of 192 items into packages (max. 12 per package) while minimizing total surface area - loading

I'm trying to solve following problem.
Given 192 items with specified length and width, I want to find a packaging order that minimizes the total surface area. The items all have the same height (which is not specified). Each package cannot contain more than 12 items, and due to the dimensions of the items it is not possible to store more than 1 item in the same layer. An item can only be stacked on top of another item if its width and length do not exceed the width and length of the lower item.
The goal is to minimize the total surface area, being the surface of the largest object (on the bottom).
I've found an extensive amount of literature on pallet and bin loading, but I can't figure out what I need exactly. Here's what I've come up with:
1) select the item i with the largest surface (width*length) and place it on the bottom of stack j.
2) select the item i with the second largest surface
a) if its width and height do not exceed stack j's bottom item's width and height, place it on top of the bottom item in stack j=1
b) if its width and height do exceed stack j's bottom item's width and height, rotate the item. If it fits, place it on top of the bottom item in stack j=1.
c) if the rotated item's width and height exceed stack j's bottom item's width and height, place it on the bottom of stack j+1 = 2
3) select the item with the third largest surface and repeat steps a, b and c
and so on...
Any remarks, or tips? I have no idea if this will yield an (optimal) solution.

Just a hint for thinking: the "can be stacked on top of" constraint defines a partial ordering of the items. The partial ordering can be represented as a graph by means of topological ordering.
Now you can consider the paths starting at every item, with length not exceeding 12. Tentative solutions can be tried by iteratively removing those paths from the graph until the graph is exhausted. (Whe you remove a path, you will have to repair other paths having items in common with it.)
It might be that the problem expressed in terms of paths is easier to solve than when expressed in terms of nodes.
An issue has to be solved: when removing a path, can it always be of the maximal length or can shorter ones yield better global solutions ?

Related

Find the rectangle with the maximum area, containing a specific point in an occupancy grid

Problem
Given an occupancy grid, for example:
...................*
*...............*...
*..*.............*..
...........*........
....................
..*.......X.........
............*.*.*...
....*..........*....
...*........*.......
..............*.....
Where, * represents an occupied block, . represents a free block and X represents a point (or block) of interest, what is the most time-efficient algorithm to find the largest rectangle which includes X, but does not include any obstacles, i.e. any *?
For example, the solution to the provided grid would be:
.....######........*
*....######.....*...
*..*.######......*..
.....######*........
.....######.........
..*..#####X.........
.....######.*.*.*...
....*######....*....
...*.######.*.......
.....######...*.....
My Thoughts
Given we have a known starting point X, I can't help but think there must be a straightforwards solution to "snap" lines to the outer boundaries to create the largest rectangle.
My current thinking is to snap lines to the maximum position offsets (i.e. go to the next row or column until you encounter an obstacle) in a cyclic manner. E.g. you propagate a horizontal line from the point X down until there is a obstacle along that line, then you propagate a vertical line left until you encounter an obstacle, then a horizontal line up and a vertical line right. You repeat this starting at with one of the four moving lines to get four rectangles, and then you select the rectangle with the largest area. However, I do not know if this is optimal, nor the quickest approach.
This problem is a well-known one in Computational Geometry. A simplified version of this problem (without a query point) is briefly described here. The problem with query point can be formulated in the following way:
Let P be a set of n points in a fixed axis-parallel rectangle B in the plane. A P-empty rectangle (or just an empty rectangle for short) is any axis-parallel rectangle that is contained in
B and its interior does not contain any point of P. We consider the problem of preprocessing
P into a data structure so that, given a query point q, we can efficiently find the largest-area
P-empty rectangle containing q.
The paragraph above has been copied from this paper, where authors describe an algorithm and data structure for the set with N points in the plane, which allow to find a maximal empty rectangle for any query point in O(log^4(N)) time. Sorry to say, it's a theoretic paper, which doesn't contain any algorithm implementation details.
A possible approach could be to somehow (implicitly) rule out irrelevant occupied cells: those that are in the "shadow" of others with respect to the starting point:
0 1 X
01234567890123456789 →
0....................
1....................
2...*................
3...........*........
4....................
5..*.......X.........
6............*.......
7....*...............
8....................
9....................
↓ Y
Looking at this picture, you could state that
there are only 3 relevant xmin values for the rectangle: [3,4,5], each having an associated ymin and ymax, respectively [(3,6),(0,6),(0,9)]
there are only 3 relevant xmax values for the rectangle: [10,11,19], each having an associated ymin and ymax, respectively [(0,9),(4,9),(4,5)]
So the problem can be reduced to finding the rectangle with the highest area out of the 3x3 set of unique combinations of xmin and xmax values
If you take into account the preparation part of selecting relevant occupied cells, this has the complexity of O(occ_count), not taking into sorting if this would still be needed and with occ_count being the number of occupied cells.
Finding the best solution (in this case 3x3 combinations) would be O(min(C,R,occ_count)²). The min(C,R) includes that you could choose the 'transpose' the approach in case R<C, (which is actually true in this example) and that that the number of relevant xmins and xmaxs have the number of occupied cells as an upper limit.

Finding area of largest rectangular that fits on a series of rectangulars

While studying I have stumbled upon an interesting problem and I am stuck.
We have a series of rectangles (base of each is 1) with varying heights, and we want to calculate area of biggest rectangle we could fit on them.
Attaching an image that I think reassembles this problem, area of red rectangles is what we want to find.
Now, I haven't yet taken DS class yet but learned some on my own, however I can't seem to find any fast solution for that. Heights can be big, like +million big, as well as total number of rectangles. Could anyone offer some guidelines please?
http://i.stack.imgur.com/Otvge.jpg
Ok, i have an idea. How about you:
Keep track of the lowest height you've seen so far. This starts at infinity.
Keep track of the number of rectangles you have seen so far, starts at 0.
Keep track of the highest area so far, this starts at 0.
While there is more rectangles
Pick the next one
lowest = min(current+lowest)
count += 1
max_area = max(max_area, lowest*count)
As an optimization, at some point you can compute that the remaining rectangles will not surpass your max area given your current, lowest boundary.
Note, this is not the exact solution, as you could discard an arbitrary number of rectangles from the beginning too, but I think this is a good general approach. Will try to extend it later if I have time.
Edit: Had further insight into it, but will leave the answer above as a "special" case solution, since it's also good. Now for the actual solution:
The limiting factor of your problem is the shortest rectangle. The area of that one will be multiplied by the total number of rectangles.
If you decide NOT to include that rectangle, you can opt for a better height and potentially a higher area.
Thus, the lowest rectangle effectively partitions your array in 2 sub-sets. To its right and to its left.
You can the consider each of these the same problem and do a recursive call.
Your method should then
If called for a single rectangle, return its area
Look for the smallest rectangle in the range.
Recursively call to the left
Recursively call to the right
Return the biggest result between right, left and smallest*range
This should be O(n2) worst case (rectangles are sorted by height), but be O(NlogN) in the general case. It would use at most O(logN) memory when computing at the bottom of the branch.
Not sure it can be done better due to the nature of the problem ;-)
Here is a simple linear solution:
Let's assume that the position of the lowest rectangle is fixed. What do we want to do then? Well, we want to find how far to the left and to the right we can go until we find a lower rectangle(let's call this positions L and R). If we know them, we can just multiply the width of all rectangle from L to R the by the the height of this rectangle and update the answer.
The part with the width is easy: we can use prefix sums.
Now let's find the leftmost lower rectangle located to the right from the given one in linear time(in total). Here is a pseudo code for this part:
s = empty stack
L = new int[n]
fill(L, -1)
for i <- 0 ... n - 1
while !s.isEmpty() && s.peek().first >= h[i]
s.pop()
if !s.isEmpty()
L[i] = s.peek().second
s.push((h[i], i)
Now we can reverse the array and compute R[i] for all i in the same.
When we have L, R, and prefix sums, we can just iterate over all rectangles to get the answer:
for i <- 0 ... n - 1
height = h[i]
width = getWidth(L[i], R[i]) // we use prefix sums in getWidth
res = max(res, height * width)
That's it.

Minimum number of rectangles in shape made from rectangles?

I'm not sure if there's an algorithm that can solve this.
A given number of rectangles are placed side by side horizontally from left to right to form a shape. You are given the width and height of each.
How would you determine the minimum number of rectangles needed to cover the whole shape?
i.e How would you redraw this shape using as few rectangles as possible?
I've can only think about trying to squeeze as many big rectangles as i can but that seems inefficient.
Any ideas?
Edit:
You are given a number n , and then n sizes:
2
1 3
2 5
The above would have two rectangles of sizes 1x3 and 2x5 next to each other.
I'm wondering how many rectangles would i least need to recreate that shape given rectangles cannot overlap.
Since your rectangles are well aligned, it makes the problem easier. You can simply create rectangles from the bottom up. Each time you do that, it creates new shapes to check. The good thing is, all your new shapes will also be base-aligned, and you can just repeat as necessary.
First, you want to find the minimum height rectangle. Make a rectangle that height, with the width as total width for the shape. Cut that much off the bottom of the shape.
You'll be left with multiple shapes. For each one, do the same thing.
Finding the minimum height rectangle should be O(n). Since you do that for each group, worst case is all different heights. Totals out to O(n2).
For example:
In the image, the minimum for each shape is highlighted green. The resulting rectangle is blue, to the right. The total number of rectangles needed is the total number of blue ones in the image, 7.
Note that I'm explaining this as if these were physical rectangles. In code, you can completely do away with the width, since it doesn't matter in the least unless you want to output the rectangles rather than just counting how many it takes.
You can also reduce the "make a rectangle and cut it from the shape" to simply subtracting the height from each rectangle that makes up that shape/subshape. Each contiguous section of shapes with +ve height after doing so will make up a new subshape.
If you look for an overview on algorithms for the general problem, Rectangular Decomposition of Binary Images (article by Tomas Suk, Cyril Höschl, and Jan Flusser) might be helpful. It compares different approaches: row methods, quadtree, largest inscribed block, transformation- and graph-based methods.
A juicy figure (from page 11) as an appetizer:
Figure 5: (a) The binary convolution kernel used in the experiment. (b) Its 10 blocks of GBD decomposition.

Rectangle packing with constraints

I want to pack a set of rectangles (example):
So that the total height is as low as possible with the constraint that the rectangles must end up in the same column they started in. The rectangles are allowed to "move" through each other to reach the final state, as long as they don't intersect at the end.
Our current algorithm is to process the rectangles from largest height to smallest height, and put them at the lowest y position that's available. Is there a more optimal algorithm?
EDIT: I don't necessarily need the optimal solution, any algorithm that generates a better solution than the current one is interesting. Also, the number of rectangles is around 50.
Suppose you have N rectangles. For each rectangle i, let [a_i, b_i] be the horizontal span, and let h_i be the height.
Your solution space looks like y_i, i = 1, ..., N, where the vertical span of rectangle i is [y_i, y_i + h_i].
Without loss of generality, we can constrain y_i >= 0. We then want to minimize the objective function max{y_i + h_i | i}.
The constraints you have for non-overlapping rectangles are:
y_i + h_i <= y_j
OR
y_j + h_j <= y_i
for all i != j such that `[a_i, b_i]` and `[a_j, b_j]` intersect
Figuring out which [a_i, b_i] intersect with each other is easy, so figuring out for which pairs of rectangles to form these constraints should be straightforward.
To get rid of the OR in our constraint, we can create binary dummy variables z_k for each constraint k and a "Big M" M that is sufficiently large and rewrite:
y_i + h_i <= y_j + (z_k)M
y_j + h_j <= y_i + (1-z_k)M
for all i != j such that `[a_i, b_i]` and `[a_j, b_j]` intersect
We can introduce a dummy variable H and add the constraints y_i + h_i <= H so that we can rewrite the objective function as minimizing H.
The resulting optimization problem is:
minimize H
with respect to: y_i, z_k, H
subject to:
(1) y_i + h_i <= y_j + (z_k)M for all i != j such that [a_i, b_i]
y_j + h_j <= y_i + (1-z_k)M and [a_j, b_j] intersect
(2) y_i + h_i <= H for all i
(3) y_i >= 0 for all i
(4) z_k in {0, 1} for all constraints of type (1) k
This is a mixed-integer linear optimization problem. There are general solvers that exist for this type of problem that you can apply directly.
Typically, they will perform tricks like relaxing the binary constraint on z_k to the constraint that z_k be in [0,1] during the algorithm, which turns this into a linear programming problem, which can be solved very efficiently.
I would not advise trying to reinvent those solvers.
Given that rectangles can only move vertically, there would appear to be only two solutions: moving all rectangles as far upward as you can until a collision occurs, or moving them all downwards until a collision occurs. I have a sneaking suspicion that these solutions are going to be equivalent*. I can't think that there's a much more sophisticated notion of packing when you're constrained to one dimension. Perhaps I'm missing something?
*If I've understood your constraint correctly, the minimal height is going to always be the number of filled cells in the column with the largest number of filled cells. This doesn't vary whether the translation is applied upwards or downwards.
In my humble opinion, the first step is to calculate, for each column, the least required height. Using your picture as an example, the first column requires at least a height of 10, which is contributed by the red, green and small blue rectangles. This is easily done by iterating through every given rectangle and add their corresponding height to the columns it occupies. By doing so, the maximum number in all the "column height" is found, which I call it the "pillar". In your picture, the "pillar" is at column 8:10 with height of 14, contributed by rectangle 1,2,4,6 (numbered from bottom to top). What this means is the minimum height of the packing is at least the height of the "pillar" since the "pillar" columns is solid filled and can't be further reduced. And stacking these four rectangle up forms such picture: (the non-pillar rectangle not shown)
Then the pillar divides the picture into two parts, one is the region to the left of pillar and another on the other side. Also, the "non-pillar" rectangles (R3,5,7,8) are separately positioned to the two regions as well. R3,R7 on the LHS and R5,R8 on the RHS.
Now consider the left side part first. I rearranged the pillar rectangles as shown it in the picture (fig.3):
With the rearranged pillar rectangle stacking order, though I don't have a rigid proof, it is highly possible that no matter what the shapes and what the number of the rectangles are positioned on the LHS of the pillar, all the given rectangles can fit in the empty space on the LHS (the constraint here is these rectangles can't give a higher solide pillar, otherwise the step 1 would have detected already and use it as the actual pillar). This arrangement gives the empty space on LHS the best "space consistency" which means the empty space created by each pillar rectangle is stacked in ascending order from bottom up. This "consistency" let the empty spaces created by each pillar rectangle to "work together" and then contain retangles that are higher than any single empty space created by single pillar rectangle. For example, the green rectangle in next picture is fit in using the empty space created by blue and purple rectangle together.
Assuming the statements above is true, then the rectangles positioned on the LHS will never make a higher stack than the pillar. However, if these retangles requires any cooperation between the empty spaces to fit in on the LHS, then they actually limit the swapping possibility for the pillar rectangles. Use fig.3 as example, the green rectangle requires the purple and blue to be neighbor to fit in, however, to get the best space consistency on RHS, the magenta has to go between the purple and blue. This means the green on LHS makes it impossible to get the best consistency for RHS and consequently makes it possible to have rectangles positioned on RHS can't fit in the empty space and cause a stack with holes and exceeds the height set by the pillar. Sorry that I can't devise such a case here, but it sure makes a difference.
In conclusion:
step 1 is to find the pillar, one easy answer can be found here if every given rectangle is involved in the pillar -- the height of the pillar is the minimum packing height.
step 2 is to examine both side to the pillar.
case a: If one side has no free rectangle positioned, then the other side can be easily filled with the "best consistency" method and resulting minimum packing height is again the pillar height.
case b: If one side doesn't require free space consistency, then that side can be filled and the other side still can use "the best consistency". For example: (your original picture)
In this case, the empty space require for fitting in R3 is solely created by R6 and the same for R7 and R2. Thus swapping the stacking order of R6 and R2 with other pillar rectangle won't make R3, R7 unfit if R3, R7 follow the swapping. Which can result in a "best consistency" case for RHS:
Then RHS can be filled with the RHS positioned rectangles without exceeding the pillar height.
This non-consistency requiring can be identified by comparing the height of the free rectangle to fit in and the height of the pillar rectangle that's to create the free space for it. If the free rectangle's height is no larger than the other's, then it doesn't require a second pillar rectangle to get involved which means it doesn't require free space consistency.
case c: Both sides need free space consistency. This is where troubles kick in. Take fig.3 as example again. The green in fig.3 had the purple and blue combined. This means the green, purple and blue is considered as a whole to swap stacking order with other pillar rectangles to get the LHS's free rectangle the best fit. And within this whole, the blue and purple can swap as well.
If the RHS can't make the fit, resulting in a packing height larger than the pillar height, then it is required to repeat the step two but with fitting the RHS first and try fitting LHS after that. Then the compared lower packing height result is taken as the final result. The logic for this case is unclear, highly possible has better alternate.
I know this should not really be called as a proper solution but rather random and loose thoughts, but it obviously won't fit in the comments. Forgive me for my clumsy explanation and poor picture handling. Hope this helps.

2D Box stacking no duplicates with height limit

I have been trying to solve a 2D variant of this problem: Box stacking problem
The catch is that unlike the original, multiple instances of the same box are not allowed. You can still rotate the 2D rectangles, of course.
There is also a height limit imposed so the tower has to be less than or equal this limit.
The base of a box below another box has to be larger than or equal to (not strictly larger) it.
I've been trying to apply the LIS algorithm and the other restrictions seem to be handled, but I cannot think of how to account for the no duplicates rule.
So my main question is how do you account for the no duplicates rule if you are trying to maximise the height of the stack and keep it below the limit?
Thanks
EDIT:
I realised that if you create the two possible rotations for each item like you do for the 3-D variant, this problem becomes very similar to the 0-1 knapsack problem. Since the optimal tower must be built using a subset of this sorted list in order then we have to choose which ones to take. However, I still don't know how to make sure no duplicates are taken. Any help on resolving this?
Thanks
EDIT 2:
I found this link: http://courses.csail.mit.edu/6.006/fall10/handouts/recitation11-19.pdf
which on page 4 describes how to solve the single-instance 3D maximum height version, however I think this will not work for the height limit version since it returns the maximum height for each call. Maybe this can be modified to accommodate the height limit?
Ok so I found out the solution was just the 0-1 style except with a boolean table after realising that the order is not important since any set of 2D rectangles can be sorted into a tower which abides by the restrictions.
Any set of 2D rectangles cannot necessarily be sorted into a tower that abides by the height restriction. Even if it could you would still need to decide which orientation to use for a particular box (rotating it so the base is largest, if it fits, would enable wider rectangles to be stacked on top but wouldn't be as tall.)
The non 0/1 version, where multiple instances of the rectangles are allowed, is solved via dynamic programming by creating two rectangles, rotated differently, sort the array of rectangles (enforcing a partial order, so that if rectangle i, with a specified rotation, can fit on top of rectangle j, with a specified rotation, then i must be less than j) and then calculate for i=0...n the maximum heights that can be achieved by a tower that ends with the ith box with a specified rotation.
The partial order is required. In the 0/1 case, where multiple rectangles/boxes are not allowed, it seems that you have to generate sets of all possible rotations of all the rectangles/boxes, sort each one and calculate its maximum height, that doesn't violate any conditions, e.g. via dynamic programming, and then keep track of the tallest stack height possible over all the subsets (Note that there are an exponential number of possible subsets which, as in the dynamic programming solution for the traveling salesman problem, is much less than the factorial number of possible orderings of a set.) In particular, the solution http://courses.csail.mit.edu/6.006/fall10/handouts/recitation11-19.pdf appears incorrect: if i < j but box i with orientation x can fit on top of box j with orientation y, then the tallest tower ending in box i with orientation x might contain box j with orientation y which wouldn't have been considered when H(i,R) was calculated, contradicting the formula.
Note that the strategy of creating duplicates also seems to fail in the 0/1 case because whether you can fit the jth box on top of the ith box depends not just on i but on whether there is a rotated version of the jth box underneath i in the stack. So it seems you need to store the highest stack that doesn't contain any possible subset of boxes in which case we are back to calculating the highest stack for every subset of boxes.

Resources