Just to remark. This is a tough (computationally-wise) problem. First, it is not Knapsack problem it appears, because your lengths are not integer.
Just a brief summary on the Knapsack anyways. It computes the problem for smaller beam lengths first and then increases the beam length gradually, solving larger problems in terms of the memorized solutions for the smaller ones. It derives the solution when the beam length reaches the target beam length from the original problem. This method requires lots and lots of memory, but promises decent performance. (Decent is very vague word when used with performance though.)
The reason why this algorithm can not be applied here is that the costs, lengths in your case, are not integral values. Consequently, growing the beam is not possible with unit steps without skipping over valid lengths. The real axis is continuous, and you can't step through real numbers, which disqualifies the Knapsack solution on Wikipedia.
This may be your problem, although I see no solution there:
http://en.wikipedia.org/wiki/Cutting_stock_problem
Some details for its complexity class you can find here, but I am not sure if they address your variant exactly:
http://cstheory.stackexchange.com/questions/1289/2d-cutting-stock-problem-for-glass-details-mentioned/1338#1338
I have tried to produce algorithm, which you must check independently. I am not sure it is bullet proof. It probably runs in polynomial time in terms of the ratio between the beam length and the piece lengths (the smallest of them or smth), but in exponential time in terms of the types of pieces that you want to support. For two pieces, this algorithm should have linear complexity, for three types of pieces - quadratic, for four - cubic. As a side note, anything above linear complexity is not really useful for large problems in practice.
Here is pseudo-code:
algorithm cutBeam(minimum usage, beam length)
if only one type of piece remains
compute how many times this piece fits in beam
if the beam usage becomes more then the minimum usage with this amount of cuts
record how many pieces were cut of this type
end if
return the beam usage
else
as long as you can cut more of the first available piece type from the beam
cut one piece of the first type from the beam
call cutBeam to get the best beam usage from the other pieces on the rest of the beam
if the total usage is greater then the minimum usage
minimum usage = current total usage
record how many pieces were cut of this type
end if
end as long
return minimum usage
end if
end algorithm |
Regards
P.S. You may try to adapt the solution on Wikipedia using binary search and some sort of set of points. I mean, you could make it work probably, but you will have to adjust it with additional tricks and the running time will probably grow by a logarithmic factor or smth like that.