views:

214

answers:

4

Alright, this might be a tricky problem. It is actually an analogy for another similar problem relating to my actual application, but I've simplified it into this hypothetical problem for clarity. Here goes:

  1. I have a line of rods I need to be sorted. Because it is a line, only 1 dimension needs to be of concern.
  2. Rods are different lengths and different weights. There is no correlation between weight and length. A small rod can be extremely heavy, while a large rod can be very light.
  3. The rods need to be sorted by weight.
  4. The real catch is, however, some rods can only be placed no more than certain distances from the start of the line, regardless of their weight. Anywhere before that is fine, though.
  5. No guarantee is given that constraints will be spaced enough away from each other to prevent the possibility of constrained rods being squeezed into overlapping. In this (hopefully rare) case, either the rods need to be re-arranged somehow within their constraints to create the needed space, or an ideal compromise solution may need to be found (such as violating a constraint of the least light rod, for example).
  6. It is possible at a future date that additional constraints may be added *in addition to the length constraint to indicate specific (and even non-compromising) boundaries within the line where rods cannot overlap into.

My current solution does not account for the latter situations, and they sound like they'll involve some complex work to resolve them.

Note that this is for a client-side web application, so making the solution apply to Javascript would be helpful!

+1  A: 

I am not very good at solving algos. But here goes my attempt:

Relate this to a Knapsack problem

  • Instead of the return cost or value of a box, let them be assigned the higher value to the ones having lesser limit of going farther.
  • Some thing like you are trying to pack everything closer to the starting point rather than into a Knapsack as per the Knapsack problem.
  • As for the future date & modification is concerned, I believe,using constraints which are similar would require a modification in the return value or cost of the box only.
loxxy
I corrected that the constraints ARE known. That was an error based on conflicting information.
Daddy Warbox
Well the constraints do not change the problem however. They still keep the bounds of the boxes.
loxxy
+2  A: 

If it is possible I'd suggest formulating this as a mixed integer program. If you can encode the constraints in this was you can use a solver to satisfy the constraints. See this page for some more info on this type of approach:

http://en.wikipedia.org/wiki/Linear_programming

If you can interface this to Javascript somehow then it might prove to be an elegant solution.

shuttle87
How would I specify my parameters in the form of a linear programming problem?
Daddy Warbox
+1  A: 

At first, I tried to approach this as a sorting problem. But I think it is better to think of it as an optimization problem. Let me try to formalize the problem. Given:

  • wi: weight of rod i
  • li: length of rod i
  • mi: maximum distance of rod i from origin. If there is no constraint, you can set this value to sum(i=1,n, li)

The problem is to find a permutation ai, such that the cost function:

J=sum(i=1,n, wai*sum(j=1,i-1, laj))

is minimized and the constraints:

sum(j=1,i-1, laj) <= mi, 1 <= i<n

are satisfied.

I am not sure this is a correct formulation, though. Without any constraints, the optimal solution is not always the rods sorted by weight. For example, let l={1,4}, and w={1,3}. If a={1,2}, then J is 1*0+3*1=3, and if a={2,1} (sorted by weight), J is 3*0+1*4=4. Clearly, the unsorted solution minimizes the cost function, but I am not sure this is what you want.

Also, I don't know how to solve the problem yet. You could try a heuristic search of some kind in the short term. I am writing this reformulation so that someone else can provide a solution while I think more about the solution. If it is correct, of course.

Another thing to note is that you don't have to find the complete solution to see if there is a solution. You can ignore the rods without position constraints, and try to solve the problem with only the constrained rods. If there is a solution to this, then the problem does have a solution (an obvious suboptimal solution is to sort the unconstrained rods, and append them to the solution of the reduced problem).


After saying all this, I think the algorithm below would do the trick. I will describe it a bit visually to make it easier to understand. The idea is to place rods on a line segment from left to right (origin is the leftmost point of the line segment) as per your problem description.

  1. Separate out the rods with position constraints on them. Then, place them such that they are at the limit of their constrained positions.
  2. If there are no overlapping rods, goto step 4
  3. For each overlapping pair of rods, move the one closer to origin towards the origin so that they are no longer overlapping. This step may require other rods on the line to be shifted towards the origin to open up some space. You detect this by checking if the moved rod now overlaps with the one just to the left of it. If you cannot create enough space (moving the rod closest to origin to 0 still doesn't free up enough space), then there is no solution to the problem. Here, you have the opportunity to find a solution by relaxing the constraint on the rightmost rod of the original overlapping pair: just move it away from origin until there is no overlap (you may need to push preceding rods right until all overlaps are fixed before you do this).
  4. Now, we have some rods placed, and some free spaces around them. Start filling up the free space with the heaviest rods (including the ones with constraints which are to the right of the free space) that would fit in it. If you cannot find any rods that would fit, simply shift the next rod on the right of the free space to close the gap.
  5. Repeat step 4 until you reach the rightmost constrained rod. The remaining line segment is all free space.
  6. Sort all left over rods by weight, and place them in the remaining free space.

A few notes about the algorithm:

  • It doesn't solve the problem I stated earlier. It tries to sort the rods according to their weights only.

  • I think there are some lost opportunities to do better, because we slide some rods towards the origin to make them all fit (in step 3), and sometimes pick the heavy rods from these "squeezed in" places, and put them closer to origin (in step 4). This frees up some room, but we don't slide the pushed away rods back to the limits of their constrained positions. It may be possible to do this, but I will have to revise the algorithm when my brain is working better.

  • It is not a terribly efficient algorithm. I have a feeling that it can be done in O(n^2), but anything better would require creative data structures. You need to be able to find the heaviest rod with length less than a given L faster than O(n) to do better.

Dysaster
Yeah, this one is a tricky. It seems I'm going to need to find a way to define and break down the problem a bit better, perhaps. Oh well, thanks for the information.
Daddy Warbox
+1  A: 

I'm 99% certain this can be cast as an integer knapsack problem with an extra constraint which, I think, can be accommodated by first considering the rods with the distance-from-start condition.

Here's a link to an explanation of the knapsack problem: http://www.g12.cs.mu.oz.au/wiki/doku.php?id=simple_knapsack

Rafe