The box stacking algorithm - algorithm

I have a question about the box stacking algorithm that was suggested here:
http://people.csail.mit.edu/bdean/6.046/dp/
The algorithm making some wrong assumption:
In the video, it says that we "sort the boxes in order of decresing base area...etc".
We do it because A box can be placed on top of another box only if both width and depth of the upper placed box are smaller than width and depth of the lower box respectively.
but if box B_1 has a base area that is bigger the box B_2, that doesn't mean that it also has its width and depth bigger than the width and depth of box B_2.
for example, a box with a 1x8 base dimensions has a bigger base area than a box with a 2x3 dimensions, but still: 1<2 (and 1<3), and therefor we cannot stack box B_2 onto B_1.
what am I missing here?

It's a question of necessary versus sufficient conditions. It's true that you can run into situations where B_2 can't be stacked on B_1, but under those circumstances, B_1 couldn't be stacked on B_2 either, so there'd be no value in switching them in the consideration order. That is, if B_a has a larger base than B_b, we know that B_a cannot be stacked on B_b (because it has at least one dimension violating the constraint).
Put differently: In the optimal stack of boxes, all are ordered by decreasing base area. So if the list of all boxes is ordered by decreasing base area, the optimal stack is guaranteed to be a subsequence of the list of all boxes -- and so, of course, is the sequence consisting of only the first k boxes. Which means that, as required by dynamic programming, when examining box k, the optimal stack which box k can rest on has already been generated during a previous round.

It is confusing how this is presented but the whole point is to find a sequence from which you can apply the LIS (least increasing subsequence) on.

Related

how to solve arrange boxes to get the smallest height problem and which algorithm to use?

how to solve this problem?
Given a group of boxes, it is requested to arrange these boxes on top of each other to reach the minimum possible height.
it is mandatory that a box “X” cannot be placed on top of another box “Y” unless the 2D base area of X is less than or equal to 2D base area of Y. It is allowed to rotated any box to use any two sides as its base. it must use only one instance of each box
Find the minimum length side of every box, and the area formed by the other two sides, in linear time. Sort by these areas in O(n log n).
This isn't a DP problem.
I dont think we can solve this using DP. I am suggesting backtracking approach.
Find all rotations possible of every box, maintain array of these possible rotations
Sort array according to their base areas
Process each box 1 by 1, check if it can be added on top of already added boxes.
When all boxes are added to stack, check if it has minimum height.
Backtrack to process these boxes in different way.
Also, we will need to have a set which will make sure only 1 instance of each box is added(before adding a box, check if box has been added in this iteration or not).
Link to famouse backtracking problem as you mentioned in comments:
https://www.geeksforgeeks.org/box-stacking-problem-dp-22/

Algorithmically expanding a box to fill a space

I have an array of box objects, defined by their (x,y,width,height) properties like so:
Box Q is anchored at corner point C. How can I programatically expand box Q to take up all the available space it has, while maintaining its aspect ratio?
I have had some luck by expanding box to be very large (from the top right corner) and then aligning to the top edge of the furthest box (in this case 5). If at that point other boxes overlap with Q, I remove the furthest box (5) and repeat (align to the top edge of 4), until no boxes overlap. The problem with this approach is that a box may overlap with Q (box 2 in the next image), but when I scale to meet its top edge, it is no longer contained, like this:
Any thoughts on an approach would be much appreciated,
Josh
but when I scale to meet its top edge, it is no longer contained
Instead scale to meet its
top edge
bottom edge
left edge
right edge
Then, see which scaling is valid (the box is contained after scaling) and results in the biggest box.
I can see two approaches here.
First is to iterate over all other boxes. For each box B, see how much (by what factor) you can expand your given box Q so that it will touch box B; after that take the minimal of all such factors. However, finding this factor for a given B is a non-trivial task, though definitely solvable.
At the same time, if you already have a code that checks for overlaps for a given factor, then you can apply binary search to find the maximal factor that does not lead to overlap.
So you know that if you expand it a lot (say by x times), it does overlap. If you do not expand it (that is, expand by 1 times), it does not overlap. So you have a segment [1,x] where to search for an answer. Try the middle --- expand by (x+1)/2 times and see whether it overlaps. If it overlaps, continue with segment [1, (x+1)/2], otherwise with segment [(x+1)/2, x]. Take the middle of the new segment, and so on until the end values of your segment are close enough.
Create a function that will take in a scaling factor as a parameter, and have it return true or false depending on if there is overlap found or not. It seems like you already have something like this function written.
Then use bisection search https://en.wikipedia.org/wiki/Bisection_method to find your scaling factor to a threshold that is satisfactory.

possible configuration of each box

Problem: You are given a set of n types of rectangular 3-D boxes, where the i^th box has height h(i), width w(i) and depth d(i) (all real numbers). You want to create a stack of boxes which is as tall as possible, but you can only stack a box on top of another box if the dimensions of the 2-D base of the lower box are each strictly larger than those of the 2-D base of the higher box. Of course, you can rotate a box so that any side functions as its base. It is also allowable to use multiple instances of the same type of box.
solution: I found the below solution at http://www.geeksforgeeks.org/dynamic-programming-set-21-box-stacking-problem/
1) Generate all 3 rotations of all boxes. The size of rotation array becomes 3 times the size of original array. For simplicity, we consider depth as always smaller than or equal to width.
2) Sort the above generated 3n boxes in decreasing order of base area.
3) After sorting the boxes, the problem is same as LIS with following optimal substructure property.
MSH(i) = Maximum possible Stack Height with box i at top of stack
MSH(i) = { Max ( MSH(j) ) + height(i) } where j < i and width(j) > width(i) and depth(j) > depth(i).
If there is no such j then MSH(i) = height(i)
4) To get overall maximum height, we return max(MSH(i)) where 0 < i < n
I think the solution is wrong as it just considers 3 rotation of all the boxes. To get the correct solution, it should generate 6 possible rotations. So, is the given solution incorrect, or is their any flaw in using 6 rotations?
Note this:
For simplicity, we consider depth as always smaller than or equal to width.
So, if the dimensions of a box are, for example, 3, 4 and 5, we consider the following three ways to put it on the stack:
d=3, w=4, h=5
d=3, w=5, h=4
d=4, w=5, h=3
The other three rotations have depth larger than width, so we do not consider them:
d=4, w=3, h=5
d=5, w=3, h=4
d=5, w=4, h=3
In order to see if one rectangle a x b can be fully covered by another one c x d, it is sufficient to turn them both so that a <= b and c <= d, and then check whether a <= c and b <= d. That's why it works.
No, it's sufficient to consider 3 "rotations" of each box, because the only possibilities to consider are which dimension to make the top and bottom (say) of the box perpendicular to, and there are only 3 of these. It might help to think of the 3 different possibilities for each box in that way, instead of as rotations.
The main point is that, after we have chosen which pair of sides of a box will be top and bottom (which we can do in 3 ways), we don't need to try the 2 different rotations of the box in the plane. We can always just go with (say) the rotation in which the box is wider than it is deep. How do we know that we won't miss any potentially good solutions by doing this? Because in any solution having a box that is deeper than it is wide, there must be a lowest such box b, and that box, plus everything above it, can be safely rotated 90 degrees. (We know it's safe to do this because it's the lowest such box in the solution -- so the box underneath it, if any, must itself be wider than it is deep, meaning that if we rotate b 90 degrees, it must still fit inside this lower box (I recommend verifying this algebraically).) We can keep transforming the lowest deeper-than-it-is-wide box in the solution until none remain, without ever changing the height of the solution. Since we can do this for any solution containing one or more deeper-than-it-is-wide boxes, it means that each one is exactly equivalent in quality to some solution in which every box is wider-than-it-is-deep, so we can totally ignore the former solutions.

Graphical algorithm for fitting in a square between a set of squares

Let's say I have n number of equally sized and equally rotated squared boxes inside a limited area in a 2D coordinate system (floating point coordinates). The boxes should not overlap.
Now I want to find a free space for one more box. I need some tips for an algorithm to solve this. Any ideas?
There ought to be a scan line algorithm for this. You say the boxes are equally rotated, so you should be able to rotate the co-ordinate system, if necessary, so that the edges of the boxes are parallel to the x and y coordinates. I would then sort the boxes in order of y coordinate.
Now try placing a box in the lowest possible position. Read from the sorted boxes to find all the boxes low enough to interfere with your placement and create an ordered set (e.g. red-black tree or similar container class) of these boxes. Now scan along this set of boxes and see if there is a gap big enough to place a box. If not, use the original sorted list of boxes to find and remove the lowest box, so you can consider putting the new box in just above that lowest box, so it cannot interfere with this. Add more boxes from the sorted list to cover all boxes high enough to interfere with this new possible height of box. Keep track of where you have removed boxes from the list and check there to see if a gap big enough to hold a box has opened up. If not, repeat the exercise until you find a gap or run out of space at the top of the possible area.
This looks like cost N log N for the initial sort, and then a cost of at most log N per box to insert and delete boxes from the ordered set. Checking for gaps is no more expensive than this, because you only check for a gap in a location where you have just removed a box. So I think the total cost is N log N.

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