60

Lets say I have a parabola. Now I also have a bunch of sticks that are all of the same width (yes my drawing skills are amazing!). How can I stack these sticks within the parabola such that I am minimizing the space it uses as much as possible? I believe that this falls under the category of Knapsack problems, but this Wikipedia page doesn't appear to bring me closer to a real world solution. Is this a NP-Hard problem?

In this problem we are trying to minimize the amount of area consumed (eg: Integral), which includes vertical area.

enter image description here

Toon Krijthe
  • 50,865
  • 37
  • 137
  • 200
rook
  • 62,960
  • 36
  • 149
  • 231
  • 1
    Better fit at mathoverflow.net? – meager Feb 22 '11 at 22:35
  • 2
    can the sticks be broken? Because if not wouldn't the requirement of 'minimizing space' be dependent on the largest stick? There could be a large gap between the largest and the next stick. An interesting problem – James Feb 22 '11 at 22:48
  • 2
    Rook- This problem can't be NP-complete because it's not a *decision problem*. For a problem to be NP-complete, it has to be in NP, which are decision problems (they all have yes/no answers). However, it could be *NP-hard*, meaning it's at least as hard as any problem in NP. You could phrase this as a decision problem "given lengths and some parabola, can you fit them in height at most h?" to make this a candidate NP-complete problem. – templatetypedef Feb 22 '11 at 22:52
  • youll have to be a bit more precise.. a rectangular stick won't fit into a parabola neatly, but will leave a gap on the bottom and on the sides. how do you define a stick fitting into a slot in the parabola? also where did you get this problem from/why do you need it answered? (seeing if there is an easier solution; if you're just curious about this in particular that's fine) – Claudiu Feb 22 '11 at 23:04
  • Probably a better fit at programmers.stackexchange – Abizern Feb 22 '11 at 23:17
  • @Rook: Are you allowed to 'stack' the sticks vertically instead of horizontally? – oosterwal Feb 22 '11 at 23:56
  • @templatetypedef good call, i haven't taken algorithms as of yet. I updated my post. – rook Feb 23 '11 at 00:54
  • @oosterwal good question, the answer is no because this does not represent the problem set accurately. – rook Feb 23 '11 at 00:56
  • 15
    @templatetypedef: While technically true, it is common convention in complexity theory to infer the equivalence between an optimization problem and its associated natural decision problem. Namely, for every optimization problem aiming to say, minimize f(x), its natural decision problem is phrased as "For a given K, does there exist some x such that f(x) < K?". In this case, the natural decision problem is: "For a given K, is there a way to stack the sticks in height < K?". – mhum Feb 23 '11 at 01:15
  • @James good question. For the purpose of this algorithm, the answer is No. Although it would make things a lot easier. – rook Feb 23 '11 at 16:14
  • 1
    The "Is this NP-hard" subthread in the comments probably belongs on math.se. The question itself probably fits equally well there or here. – Ben Voigt Feb 24 '11 at 02:48
  • The sum of the areas of the sticks is the same however they are placed. – Colonel Panic Apr 17 '13 at 23:45
  • @Colonel Panic and that is not the problem that is described nor does this comment help with the real world problem that was solved more than year ago. – rook Apr 18 '13 at 04:52

7 Answers7

23

I cooked up a solution in JavaScript using processing.js and HTML5 canvas.

This project should be a good starting point if you want to create your own solution. I added two algorithms. One that sorts the input blocks from largest to smallest and another that shuffles the list randomly. Each item is then attempted to be placed in the bucket starting from the bottom (smallest bucket) and moving up until it has enough space to fit.

Depending on the type of input the sort algorithm can give good results in O(n^2). Here's an example of the sorted output.

Sorted insertion

Here's the insert in order algorithm.

function solve(buckets, input) {
  var buckets_length = buckets.length,
      results = [];

  for (var b = 0; b < buckets_length; b++) {
    results[b] = [];
  }

  input.sort(function(a, b) {return b - a});

  input.forEach(function(blockSize) {
    var b = buckets_length - 1;
    while (b > 0) {
      if (blockSize <= buckets[b]) {
        results[b].push(blockSize);
        buckets[b] -= blockSize;
        break;
      }
      b--;
    }
  });

  return results;
}

Project on github - https://github.com/gradbot/Parabolic-Knapsack

It's a public repo so feel free to branch and add other algorithms. I'll probably add more in the future as it's an interesting problem.

gradbot
  • 13,374
  • 5
  • 34
  • 68
  • 2
    This **[First Fit Decreasing](http://en.wikipedia.org/wiki/Bin_packing_problem#First-fit_algorithm)** algorithm can be far from optimal. [See how First Fit Decreasing can go wrong (left side).](http://www.jboss.org/drools/drools-planner/mainColumnParagraphs/02/image/binPackingUseCase.png) But **it is a very good starting point** and it's very fast. If you need more (which you might not), especially if you want to avoid that a human looks at it and goes *look if you switch those 2 it's even better*, take the result of that algorithm and throw meta-heuristics on it: that will approve upon that. – Geoffrey De Smet Mar 23 '11 at 12:50
15

Simplifying

First I want to simplify the problem, to do that:

  • I switch the axes and add them to each other, this results in x2 growth
  • I assume it is parabola on a closed interval [a, b], where a = 0 and for this example b = 3

Lets say you are given b (second part of interval) and w (width of a segment), then you can find total number of segments by n=Floor[b/w]. In this case there exists a trivial case to maximize Riemann sum and function to get i'th segment height is: f(b-(b*i)/(n+1))). Actually it is an assumption and I'm not 100% sure.

Max'ed example for 17 segments on closed interval [0, 3] for function Sqrt[x] real values:

enter image description here

And the segment heights function in this case is Re[Sqrt[3-3*Range[1,17]/18]], and values are:

  • Exact form:

{Sqrt[17/6], 2 Sqrt[2/3], Sqrt[5/2], Sqrt[7/3], Sqrt[13/6], Sqrt[2], Sqrt[11/6], Sqrt[5/3], Sqrt[3/2], 2/Sqrt[3], Sqrt[7/6], 1, Sqrt[5/6], Sqrt[2/3], 1/Sqrt[2], 1/Sqrt[3], 1/Sqrt[6]}

  • Approximated form:

{1.6832508230603465, 1.632993161855452, 1.5811388300841898, 1.5275252316519468, 1.4719601443879744, 1.4142135623730951, 1.35400640077266, 1.2909944487358056, 1.224744871391589, 1.1547005383792517, 1.0801234497346435, 1, 0.9128709291752769, 0.816496580927726, 0.7071067811865475, 0.5773502691896258, 0.4082482904638631}

What you have archived is a Bin-Packing problem, with partially filled bin.

Finding b

If b is unknown or our task is to find smallest possible b under what all sticks form the initial bunch fit. Then we can limit at least b values to:

  1. lower limit : if sum of segment heights = sum of stick heights
  2. upper limit : number of segments = number of sticks longest stick < longest segment height

One of the simplest way to find b is to take a pivot at (higher limit-lower limit)/2 find if solution exists. Then it becomes new higher or lower limit and you repeat the process until required precision is met.


When you are looking for b you do not need exact result, but suboptimal and it would be much faster if you use efficient algorithm to find relatively close pivot point to actual b.

For example:

  • sort the stick by length: largest to smallest
  • start 'putting largest items' into first bin thy fit
Margus
  • 18,332
  • 12
  • 51
  • 101
  • Your upper limit is trivially wrong (take one stick which is longer than the lowest bin) – Ben Voigt Feb 24 '11 at 02:52
  • @Ben Voigt : You are correct, that was a careless mistake. Ty, for taking the time to point it out. – Margus Feb 24 '11 at 03:00
  • Worst case, I think you need to add those two together (e.g. 4 sticks all 100 long, the optimal solution is to occupy rows 10, 11, 12, 13) – Ben Voigt Feb 24 '11 at 04:52
  • This seems to be the "programmer" version of the solution. Now that I read you post, I saw the similarities. But as your post does not show that this problem is not in P (which only makes one stop wasting time searching for a better solution) Readers may be interested in the more or less informal two-way reduction in my answer (which I admit needs some complexity theory context to grasp) – sleeplessnerd Mar 23 '11 at 01:00
12

This is equivalent to having multiple knapsacks (assuming these blocks are the same 'height', this means there's one knapsack for each 'line'), and is thus an instance of the bin packing problem.

See http://en.wikipedia.org/wiki/Bin_packing

dfb
  • 12,827
  • 1
  • 26
  • 52
  • I think this is 1/2 the problem. How do you do this in the least number of bins? – rook Feb 22 '11 at 22:48
  • 5
    @spintheblack- Your reduction is in the wrong direction. You've shown that you can turn this into bin-packing, but that just says that bin packing is at least as hard as this problem. You need to show the opposite direction - that any instance of bin-packing can be turned into an instance of this problem - to show that this problem is at least as hard as the NP-hard bin-packing problem. – templatetypedef Feb 22 '11 at 22:48
  • Depends - are you trying to minimize vertical space? If not, then any packing will have the equivalent amount of space, I think,. – dfb Feb 22 '11 at 22:49
  • @spintheblack yeah, minimize the vertical space. – rook Feb 22 '11 at 22:53
  • @templatetypedef - This is true, this was more a pointer than a proof. I think the obvious reduction, create a shape of width x for each bin, is probably the right direction, though. – dfb Feb 22 '11 at 22:53
  • @spintheblack- I'm not convinced that this can easily be reduced from bin packing because the parabola admits bins of a certain size. I'll think it over and see if I can come up with anything. – templatetypedef Feb 22 '11 at 22:54
  • @templatetypedef - You could be right on that front... digging myself as well. – dfb Feb 22 '11 at 22:57
  • @Rook - Bin packing tries to use the least number of bins. One of the wrinkles here is that we have to use the 'bottom bin' before any of the other ones. Also, as noted above, we have different sizes. – dfb Feb 22 '11 at 22:58
  • @templatetypedef: would indeed be fascinating if bins whose sizes correspond to a parabola was not an NP-Hard problem. i suspect it is, though, will have to figure out how to prove it – Claudiu Feb 22 '11 at 23:00
  • It's been a while since I've done a reduction proof, so forgive me if this is off - Doesn't the hardness of this problem follow from the fact that bin-packing is a special case of this problem? That is uniform lengths is a subset of multiple lengths (Variable Size Bin Packing Problem as the literature seems to call it). The order of the bins as chosen by our hypothetical algorithm doesn't matter since they are all the same. As far as how well the approximation algorithm works, I'm not sure.. – dfb Feb 22 '11 at 23:20
  • 4
    @spintheblack: Bin-packing is not a special case of this problem (in any obvious way). The bins in classic bin-packing are all the same size while the bin sizes here are variable. Moreover, if we expand the classic bin-packing problem to include variable-sized bins, we still have the issue that the bin sizes in this problem are restricted to a particular form. – mhum Feb 23 '11 at 01:12
  • It's not exactly equivalent because in the parabolic knapsack your aim is to stay as low as possible inside the parabola. Think about it the parabola will at one point wide enough to contain all blocks in one row (=one bin), but the wasted area will be immense. – Dave O. Feb 23 '11 at 02:09
  • @mhum - Unless I'm misunderstanding the problem above, the bin sizes are constant but don't varied (distinction: they cannot be grown or shrunken). Maybe the confusion here is that we're restricting this to an actual parabola? (see picture :), I didn't take the parabola literally on my early comments), Otherwise in the bin packing, we have bins of size K and in this we have bins of variable size, I don't see why bin-packing isn't a special case. – dfb Feb 23 '11 at 03:16
  • Just waffling here, but another thought - since we're effectively discretizing the parabola and the input to the problem presumably takes as input the parameters for the parabolic function and some i.e., x value cutoff, it seems unlikely that this has any special form that'll be exploitable. At the very least, if we want to get into the nitty gritty, we need more details from the OP – dfb Feb 23 '11 at 03:25
  • @spintheblack Hah, it s an actual parabola! (or a segment of a sine wave). Also I am happy to provide more details into this problem, but if I'm not mistaken you guys are on the right track. – rook Feb 23 '11 at 03:54
  • @spintheblack: Perhaps I'm not understanding your formulation. What are the items and what are the bins? I assumed that the sticks were the items and the bins were horizontal sections of the parabola induced by where the sticks may be placed. – mhum Feb 23 '11 at 04:12
  • 1
    @mhum - What you wrote is what I was going by, so maybe I'm missing something. If you agree that the bin packing problem is a special case of the multiple size bin packing problem with ordered bins (bin x_1 <= x_2 <= ... and they must be packed in ascending order) then I think we're on the same page. – dfb Feb 23 '11 at 16:47
  • @spintheblack Yeah we are on the same page. – rook Feb 23 '11 at 18:34
  • @spintheblack: Ah. I think I see the problem. This parabolic packing problem is not (evidently) equivalent to the multiple size bin packing problem. It is a special case of the multiple size bin packing problem (just like, as you say, the standard bin packing problem). It requires proof to show that this special instance of the multiple size bin packing problem is equivalent to, say, the standard bin packing problem. The fact that they are both special cases of the same parent problem does not give this conclusion. – mhum Feb 23 '11 at 23:36
  • Another difference that no one seems to have mentioned is the fact that if you pack a really narrow stick by itself at the bottom, it will fit lower than a wider stick. That could be good or bad. It potentially defines the sizes of all the other bins. However, if the next biggest stick were so large that it can't rest on top of the smallest stick, then there's a new custom bin exactly its size (at the expense of a wasted half-bin perhaps between them). This makes it quite different from standard bin packing. – JCooper Mar 22 '11 at 16:42
2

How can I stack these sticks within the parabola such that I am minimizing the (vertical) space it uses as much as possible?

Just deal with it like any other Bin Packing problem. I'd throw meta-heuristics on it (such as tabu search, simulated annealing, ...) since those algorithms aren't problem specific.

For example, if I'd start from my Cloud Balance problem (= a form of Bin Packing) in Drools Planner. If all the sticks have the same height and there's no vertical space between 2 sticks on top of each other, there's not much I'd have to change:

  • Rename Computer to ParabolicRow. Remove it's properties (cpu, memory, bandwith). Give it a unique level (where 0 is the lowest row). Create a number of ParabolicRows.
  • Rename Process to Stick
  • Rename ProcessAssignement to StickAssignment
  • Rewrite the hard constraints so it checks if there's enough room for the sum of all Sticks assigned to a ParabolicRow.
  • Rewrite the soft constraints to minimize the highest level of all ParabolicRows.
Geoffrey De Smet
  • 22,431
  • 8
  • 59
  • 106
2

I'm very sure it is equivalent to bin-packing:

informal reduction

Be x the width of the widest row, make the bins 2x big and create for every row a placeholder element which is 2x-rowWidth big. So two placeholder elements cannot be packed into one bin.

To reduce bin-packing on parabolic knapsack you just create placeholder elements for all rows that are bigger than the needed binsize with size width-binsize. Furthermore add placeholders for all rows that are smaller than binsize which fill the whole row.

This would obviously mean your problem is NP-hard.

For other ideas look here maybe: http://en.wikipedia.org/wiki/Cutting_stock_problem

sleeplessnerd
  • 18,543
  • 1
  • 22
  • 29
1

Props to those who mentioned the fact that the levels could be at varying heights (ex: assuming the sticks are 1 'thick' level 1 goes from 0.1 unit to 1.1 units, or it could go from 0.2 to 1.2 units instead)

You could of course expand the "multiple bin packing" methodology and test arbitrarily small increments. (Ex: run the multiple binpacking methodology with levels starting at 0.0, 0.1, 0.2, ... 0.9) and then choose the best result, but it seems like you would get stuck calulating for an infinite amount of time unless you had some methodlogy to verify that you had gotten it 'right' (or more precisely, that you had all the 'rows' correct as to what they contained, at which point you could shift them down until they met the edge of the parabola)

Also, the OP did not specify that the sticks had to be laid horizontally - although perhaps the OP implied it with those sweet drawings.

I have no idea how to optimally solve such an issue, but i bet there are certain cases where you could randomly place sticks and then test if they are 'inside' the parabola, and it would beat out any of the methodologies relying only on horizontal rows. (Consider the case of a narrow parabola that we are trying to fill with 1 long stick.)

I say just throw them all in there and shake them ;)

Allen
  • 887
  • 7
  • 18
1

Most likely this is the 1-0 Knapsack or a bin-packing problem. This is a NP hard problem and most likely this problem I don't understand and I can't explain to you but you can optimize with greedy algorithms. Here is a useful article about it http://www.developerfusion.com/article/5540/bin-packing that I use to make my php class bin-packing at phpclasses.org.

Gigamegs
  • 12,342
  • 7
  • 31
  • 71