Optimal ice cream cone filling process on a conveyor belt with arbitrary distributed cones [closed] - algorithm

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have an algorithmic question that arose from a real-life production problem.
Setting. Empty ice cream cones are randomly distributed across a moving conveyor belt. The batcher equipment has a hosepipe that can move above the belt within some limits (considerably smaller than the length of the belt). In order to fill an empty cone the hosepipe is placed right above the cone and locked on it for some time until the filling process is over. So this means that the cone must remain in the hosepipe reach area while the filling is in progress. After it's done the hosepipe can move on to another cone. Clearly, if the speed is not big enough and filling process takes some time the system would miss some of the cones if cones are many enough and inconveniently placed. So the problem is to fill as much cones as possible by scheduling the order of filling beforehand.
Formally we have as input:
U — speed of the belt
V — speed of the hosepipe
W — width of the belt
L — length of the belt
P — length of the hosepipe reach area
T — time of the filling process
cones — array of coordinates of cones on the belt
An output is ideally the list of cones to fill successively that ensures the maximum number of filled cones. Or at least an estimation of the maximal number of cones that are possible to fill.
Any suggestions on how to tackle this problem would be greatly appreciated!

Optimal cone-filling with a forward-only dispenser
Let's suppose the conveyor belt moves right-to-left. Below I'll describe a way to formulate and solve the problem in a way that fills the maximum possible number of cones, under the assumption that the dispenser never moves to the left faster than the conveyor belt does. For n cones, the basic algorithm has a very loose (see later) upper bound of O(n^3) time and O(n^2) space -- this should be feasible for up to 1000 cones or so. If you have more cones than this, you can break them into blocks of at most this size and simply process each block one after the other. There's also a way to relax the never-move-left-fast restriction somewhat, and thus potentially fill more cones, without the whole problem becoming exponential-time -- I'll describe this later.
Let's suppose that all cones have positive x co-ordinates, and that the hosepipe reach area, which initially extends from x = 0 leftwards to x = -P, moves rightwards over the cones, which themselves remain stationary. So at time t, the hosepipe reach area will extend from x = U * t leftwards to x = U * t - P. When describing the position of the dispenser, I'll always use the same (that is, absolute) co-ordinate system; we'll ensure that it remains a valid position (inside the hosepipe reach area) by ensuring that at any time t, its x location is between U * t - P and U * t. Notice that a (time, cone ID) pair is enough to completely determine the positions of both the hosepipe reach area and the dispenser, if we interpret it to mean that the dispenser is directly over the given cone at the given time. (Later this will help in simplifying the description of the system state.) Finally, I'll call any motion of the dispenser that does not decrease its absolute x co-ord (this includes any backward motion, relative to its enclosure, that is lower in speed than U, and also no motion at all) a "forward" motion, and any that does a "backward" motion.
Dynamic programming formulation
Sort the cones by increasing x position, breaking ties arbitrarily. Let (x_i, y_i) be the position of the ith cone in this sorted order.
Let e(i) be the earliest time at which we could feasibly position the dispenser over cone i if it was the only cone we cared about, and the dispenser was already "waiting" at the correct vertical position (namely, y_i) at the rightmost end of the hosepipe reach area: this is simply x_i / U.
Let m(i, j) be the time needed to move the dispenser from cone i to cone j, assuming that it's possible to do so without having to wait for either one to "scroll into view": this can easily be calculated for any pair (i, j) from their co-ordinates and the speeds V and U (this remains true even if the dispenser can simultaneously move at arbitrary speeds V_x and V_y in the x and y directions).
Now we come to the function that is the key to efficient solution of this problem:
Let f(i, j) be the earliest time at which we could finish filling cone i such that we have filled exactly j cones so far (including this one, so 1 <= j <= i), or infinity if this is not feasible. Let g(i, j) be a helper function that is defined the same way, except that we allow the last cone-filling step to push the dispenser too far to the left (you'll see why in a minute). We can calculate g(i, j) and, more importantly, f(i, j) as follows:
g(i, j) = max(e(i), minimum of f(k, j-1) + m(k, i) over all k s.t. j <= k < i) + T
f(i, j) = IF U * g(i, j) - P <= x_i THEN g(i, j) ELSE infinity
What a mess! Let's go part by part.
The f(k, j-1) + m(k, i) term is the smallest amount of time it takes to fill j-1 cones, ending with cone k, then move the dispenser to cone i. The max(e(i), ...) around this ensures that, if the movement implied by the above term would cause the dispenser to move too far to the right (i.e., to some x-co-ord > U * t), it won't be taken. Instead, we'll move the dispenser to (U * t, y_i) -- that is, to the correct y co-ord for cone i and as far right as possible -- then wait for cone i to scroll in (and thus appear directly below the dispenser) at time e(i). Regardless of which of these actions we take, it then takes a further T time units to fill cone i.
(Technically, the above calculation assumes that, if it's possible to move the dispenser to (x_i, y_i) by some given time t, then it's also possible to move it to (U * t < x_i, y_i) by that same time at the latest. But since our starting x location is <= U * t, the only way this could fail to hold is if the function describing the time needed to move between 2 given points violates the Triangle Inequality -- something which doesn't happen when the hosepipe moves relative to its enclosure at a constant speed V, or independently in 2 directions at constant speeds V_x and V_y, or indeed uses any non-crazy drive system.)
What about the left edge of the hosepipe reach area? U * g(i, j) - P is the position of the left edge of the this area at the time g(i, j). Since that time is the earliest possible time that we could have finished the task of filling j cones, the last of which is cone i, that expression gives the leftmost possible position that the left edge of the hosepipe reach area could be in when the task is completed. So if that position is still to the left of x_i, it means we can feasibly fill cone i after those j-1 earlier cones -- but if it isn't, we know that trying to do so will force the dispenser too far left (this might happen while trying to move to cone i, or while filling it -- it doesn't matter). So in the latter case we slam the time cost associated with task f(i, j) all the way to infinity, guaranteeing it won't be used as part of the solution to any larger subproblem.
Time and space usage
Calculating any particular f(i, j) value takes O(n) time, so calculating all O(n^2) of these values takes O(n^3) time. However in practice, we will hardly ever need to consider all possible values of k less than i in the above minimum. In addition to ensuring that the sequence of movements implied by f(i, j) remains feasible, the max(e(i), ...) is also the key to a big practical speedup: as soon as we happen on a k that causes the e(i) term to "kick in" (become the larger of the two terms compared by max()), it will remain the best feasible option -- since any subsequent k that purports to allow a faster completion of the task necessarily involves pushing the dispenser too far to the right in the final step. That means that we don't need to try any of those other k values: e(i) is indeed the real minimum.
If all we wanted to calculate was the minimum time needed to fill some given number of cones, we could actually do it in just O(n) space, by making use of the fact that when calculating f(i, j), we only ever access previous values of f() having second argument equal to j-1. But since what we actually really want is the sequence of actions corresponding to such a minimum time, we will need to record a table of predecessors p[i][j], and this does require O(n^2) space.
Pseudocode
Sort cone[1 .. n] by increasing x co-ord.
Compute e[i] for all 1 <= i <= n.
Set f[i][1] = e[i] + T for all 1 <= i <= n.
Set f[i][j] = infinity for all 1 <= i <= n, 2 <= j <= i.
maxCones = 0.
bestTime = infinity.
# Compute f(i, j) for all i, j.
For j from 2 up to n:
For i from j up to n:
g = infinity. # Best time for f(i, j) so far.
For k from j up to i-1:
z = f[k][j-1] + m(k, i) + T.
If z < g:
p[i][j] = k.
If z < e[i] + T:
g = e[i] + T.
Break out of innermost (k) loop.
Else:
g = z.
If U * g - P <= cone[i].x:
f[i][j] = g.
If maxCones < j or (maxCones == j and g < bestTime):
maxCones = j. # New record!
bestI = i.
bestTime = g.
Else:
f[i][j] = infinity.
# Trace back through p[][] to find the corresponding action sequence.
For j from maxCones down to 1:
fill[j] = bestI.
bestI = p[bestI][j].
After running this, maxCones will contain the maximum number of cones that can feasibly be filled, and if this is >= 1, then fill[1] through fill[maxCones] will contain a corresponding sequence of maxCone cone IDs (positions in the sorted sequence) to fill, and the total time needed will be in bestTime.
Possible enhancements
The above algorithm only solves the problem optimally under the restriction that the dispenser never moves backwards "too fast". This could be quite restrictive in practice: For example, a pattern of cones like the following
X X X X
X X X X
will cause the dispenser make a long vertical move between every cone it fills (assuming it's able to fill all of them). Filling several cones in the same row and only then moving to the other row would save a lot of time.
The difficulty in solving the problem optimally without the restriction above is that it starts looking very much like certain NP-hard problems, like the Euclidean TSP problem. I don't have time to look for a formal reduction, but I'm confident that the unrestricted version of your problem is NP-hard, so the best we can hope to do with a polynomial-time algorithm is to look for good heuristics. To that end:
The DP solution above basically finds, for each cone i, the best way to fill j cones in total, ending at cone i and using only other cones to its left. We can solve a slightly more general problem by breaking the sorted sequence of cones into contiguous blocks of b cones, and then finding, for each cone i, the best way to fill j cones in total that ends at cone i and uses only the cones that are either (a) in an earlier block (these cones must be to the left of i) or (b) in the same block as i (these cones aren't, necessarily). The only solutions overlooked by this approach are those that would require us to fill a cone in some block and afterwards fill a cone in an earlier block (this includes, in particular, all solutions where we fill a cone in some block, a cone in a different block, and then another cone in the first block again -- at least one of the two moves between blocks must be a move to a previous block).
Obviously, if we pick b = n then this will find the overall optimum (in a million years), but b doesn't need to be anywhere near this large to get an optimal solution. Using a variation of the O(n^2*2^n) DP algorithm for solving TSP to assist in computing within-block optimal paths, choosing b = 10, say, would be quite feasible.
One more suggestion is that instead of fixing the block size at exactly b, cones could first be more intelligently split into blocks of size at most b, that is, in such a way that the (unknown) optimal solution seldom needs to fill a cone in a previous block. In fact, provided that it's possible to heuristically score breakpoint "quality" (e.g. by using the minimum distance between any pair of points in 2 blocks), calculating a blocking pattern that maximises the score can easily be done in O(bn) time, using a (different) DP!

Related

Finding closest pair of points in the plane with non-distinct x-coordinates in O(nlogn)

Most of the implementations of the algorithm to find the closest pair of points in the plane that I've seen online have one of two deficiencies: either they fail to meet an O(nlogn) runtime, or they fail to accommodate the case where some points share an x-coordinate. Is a hash map (or equivalent) required to solve this problem optimally?
Roughly, the algorithm in question is (per CLRS Ch. 33.4):
For an array of points P, create additional arrays X and Y such that X contains all points in P, sorted by x-coordinate and Y contains all points in P, sorted by y-coordinate.
Divide the points in half - drop a vertical line so that you split X into two arrays, XL and XR, and divide Y similarly, so that YL contains all points left of the line and YR contains all points right of the line, both sorted by y-coordinate.
Make recursive calls for each half, passing XL and YL to one and XR and YR to the other, and finding the minimum distance, d in each of those halves.
Lastly, determine if there's a pair with one point on the left and one point on the right of the dividing line with distance smaller than d; through a geometric argument, we find that we can adopt the strategy of just searching through the next 7 points for every point within distance d of the dividing line, meaning the recombination of the divided subproblems is only an O(n) step (even if it looks n2 at first glance).
This has some tricky edge cases. One way people deal with this is sorting the strip of points of distance d from the dividing line at every recombination step (e.g. here), but this is known to result in an O(nlog2n) solution.
Another way people deal with edge cases is by assuming each point has a distinct x-coordinate (e.g. here): note the snippet in closestUtil which adds to Pyl (or YL as we call it) if the x-coordinate of a point in Y is <= the line, or to Pyr (YR) otherwise. Note that if all points lie on the same vertical line, this would result us writing past the end of the array in C++, as we write all n points to YL.
So the tricky bit when points can have the same x-coordinate is dividing the points in Y into YL and YR depending on whether a point p in Y is in XL or XR. The pseudocode in CLRS for this is (edited slightly for brevity):
for i = 1 to Y.length
if Y[i] in X_L
Y_L.length = Y_L.length + 1;
Y_L[Y_L.length] = Y[i]
else Y_R.length = Y_R.length + 1;
Y_R[Y_R.length] = Y[i]
However, absent of pseudocode, if we're working with plain arrays, we don't have a magic function that can determine whether Y[i] is in X_L in O(1) time. If we're assured that all x-coordinates are distinct, sure - we know that anything with an x-coordinate less than the dividing line is in XL, so with one comparison we know what array to partition any point p in Y into. But in the case where x-coordinates are not necessarily distinct (e.g. in the case where they all lie on the same vertical line), do we require a hash map to determine whether a point in Y is in XL or XR and successfully break down Y into YL and YR in O(n) time? Or is there another strategy?
Yes, there are at least two approaches that work here.
The first, as Bing Wang suggests, is to apply a rotation. If the angle is sufficiently small, this amounts to breaking ties by y coordinate after comparing by x, no other math needed.
The second is to adjust the algorithm on G4G to use a linear-time partitioning algorithm to divide the instance, and a linear-time sorted merge to conquer it. Presumably this was not done because the author valued the simplicity of sorting relative to the previously mentioned algorithms in most programming languages.
Tardos & Kleinberg suggests annotating each point with its position (index) in X.
You could do this in N time, or, if you really, really want to, you could do it "for free" in the sorting operation.
With this annotation, you could do your O(1) partitioning, and then take the position pr of the right-most point in Xl in O(1), using it to determine weather a point in Y goes in Yl (position <= pr), or Yr (position > pr). This does not require an extra data structure like a hash map, but it does require that those same positions are used in X and Y.
NB:
It is not immediately obvious to me that the partitioning of Y is the only problem that arises when multiple points have the same coordinate on the x-axis. It seems to me that the proof of linearity of the comparisons neccesary across partitions breaks, but I have seen only the proof that you need only 15 comparisons, not the proof for the stricter 7-point version, so i cannot be sure.

How many paths of length n with the same start and end point can be found on a hexagonal grid?

Given this question, what about the special case when the start point and end point are the same?
Another change in my case is that we must move at every step. How many such paths can be found and what would be the most efficient approach? I guess this would be a random walk of some sort?
My think so far is, since we must always return to our starting point, thinking about n/2 might be easier. At every step, except at step n/2, we have 6 choices. At n/2 we have a different amount of choices depending on if n is even or odd. We also have a different amount of choices depending on where we are (what previous choices we made). For example if n is even and we went straight out, we only have one choice at n/2, going back. But if n is even and we didn't go straight out, we have more choices.
It is all the cases at this turning point that I have trouble getting straight.
Am I on the right track?
To be clear, I just want to count the paths. So I guess we are looking for some conditioned permutation?
This version of the combinatorial problem looks like it actually has a short formula as an answer.
Nevertheless, the general version, both this and the original question's, can be solved by dynamic programming in O (n^3) time and O (n^2) memory.
Consider a hexagonal grid which spans at least n steps in all directions from the target cell.
Introduce a coordinate system, so that every cell has coordinates of the form (x, y).
Let f (k, x, y) be the number of ways to arrive at cell (x, y) from the starting cell after making exactly k steps.
These can be computed either recursively or iteratively:
f (k, x, y) is just the sum of f (k-1, x', y') for the six neighboring cells (x', y').
The base case is f (0, xs, ys) = 1 for the starting cell (xs, ys), and f (0, x, y) = 0 for every other cell (x, y).
The answer for your particular problem is the value f (n, xs, ys).
The general structure of an iterative solution is as follows:
let f be an array [0..n] [-n-1..n+1] [-n-1..n+1] (all inclusive) of integers
f[0][*][*] = 0
f[0][xs][ys] = 1
for k = 1, 2, ..., n:
for x = -n, ..., n:
for y = -n, ..., n:
f[k][x][y] =
f[k-1][x-1][y] +
f[k-1][x][y-1] +
f[k-1][x+1][y] +
f[k-1][x][y+1]
answer = f[n][xs][ys]
OK, I cheated here: the solution above is for a rectangular grid, where the cell (x, y) has four neighbors.
The six neighbors of a hexagon depend on how exactly we introduce a coordinate system.
I'd prefer other coordinate systems than the one in the original question.
This link gives an overview of the possibilities, and here is a short summary of that page on StackExchange, to protect against link rot.
My personal preference would be axial coordinates.
Note that, if we allow standing still instead of moving to one of the neighbors, that just adds one more term, f[k-1][x][y], to the formula.
The same goes for using triangular, rectangular, or hexagonal grid, for using 4 or 8 or some other subset of neighbors in a grid, and so on.
If you want to arrive to some other target cell (xt, yt), that is also covered: the answer is the value f[n][xt][yt].
Similarly, if you have multiple start or target cells, and you can start and finish at any of them, just alter the base case or sum the answers in the cells.
The general layout of the solution remains the same.
This obviously works in n * (2n+1) * (2n+1) * number-of-neighbors, which is O(n^3) for any constant number of neighbors (4 or 6 or 8...) a cell may have in our particular problem.
Finally, note that, at step k of the main loop, we need only two layers of the array f: f[k-1] is the source layer, and f[k] is the target layer.
So, instead of storing all layers for the whole time, we can store just two layers, as we don't need more: one for odd k and one for even k.
Using only two layers is as simple as changing all f[k] and f[k-1] to f[k%2] and f[(k-1)%2], respectively.
This lowers the memory requirement from O(n^3) down to O(n^2), as advertised in the beginning.
For a more mathematical solution, here are some steps that would perhaps lead to one.
First, consider the following problem: what is the number of ways to go from (xs, ys) to (xt, yt) in n steps, each step moving one square north, west, south, or east?
To arrive from x = xs to x = xt, we need H = |xt - xs| steps in the right direction (without loss of generality, let it be east).
Similarly, we need V = |yt - ys| steps in another right direction to get to the desired y coordinate (let it be south).
We are left with k = n - H - V "free" steps, which can be split arbitrarily into pairs of north-south steps and pairs of east-west steps.
Obviously, if k is odd or negative, the answer is zero.
So, for each possible split k = 2h + 2v of "free" steps into horizontal and vertical steps, what we have to do is construct a path of H+h steps east, h steps west, V+v steps south, and v steps north. These steps can be done in any order.
The number of such sequences is a multinomial coefficient, and is equal to n! / (H+h)! / h! / (V+v)! / v!.
To finally get the answer, just sum these over all possible h and v such that k = 2h + 2v.
This solution calculates the answer in O(n) if we precalculate the factorials, also in O(n), and consider all arithmetic operations to take O(1) time.
For a hexagonal grid, a complicating feature is that there is no such clear separation into horizontal and vertical steps.
Still, given the starting cell and the number of steps in each of the six directions, we can find the final cell, regardless of the order of these steps.
So, a solution can go as follows:
Enumerate all possible partitions of n into six summands a1, ..., a6.
For each such partition, find the final cell.
For each partition where the final cell is the cell we want, add multinomial coefficient n! / a1! / ... / a6! to the answer.
Just so, this takes O(n^6) time and O(1) memory.
By carefully studying the relations between different directions on a hexagonal grid, perhaps we can actually consider only the partitions which arrive at the target cell, and completely ignore all other partitions.
If so, this solution can be optimized into at least some O(n^3) or O(n^2) time, maybe further with decent algebraic skills.

Choice of optimization algorithm for distributing lines inside a shape

Consider the follow representation of a concrete slab element with reinforcement bars and holes.
I need an algorithm that automatically distributes lines over an arbitrary shape with different holes.
The main constraints are:
Lines cannot be outside of the region or inside a hole
The distance between two side-by-side lines cannot exceed a variable D
Lines have to be positioned on a fixed interval I, i.e. y mod I = 0, where y is the line's Y coordinate.
Each available point inside the shape cannot be further from a line than D/2
I want to optimize the solution by minimizing the total number of lines N. What kind of optimization algorithm would suit this problem?
I assume most approaches involves simplifying the shape into a raster (with pixel height I) and disable or enable each pixel. I thought this was an obvious LP problem and tried to set it up with GLPK, but found it very hard to describe the problem using this simplified raster for an arbitrary number of lines. I also suspect that the solution space might be too big.
I have already implemented an algorithm in C# that does the job, but not very optimized. This is how it works:
Create a simplified raster of the geometry
Calculate a score for each cell using a complicated formula that takes possible line length and distances to other rods and obstacles into account.
Determine which needs reinforcement (where number of free cells in y direction > D)
Pick the cell with the highest score that needs reinforcement, and reinforce it as far as possible in -x and +x directions
Repeat
Depending on the complicated formula, this works pretty well but starts giving unwanted results when putting the last few lines, since it can never move an already put line.
Are there any other optimization techniques that I should have a look at?
I'm not sure what follows is what you want - I'm fairly sure it's not what you had in mind - but if it sounds reasonable you might try it out.
Because the distance is simply at most d, and can be anything less than that, it seems at first blush like a greedy algorithm should work here. Always place the next line(s) so that (1) as few as possible are needed and (2) they are as far away from existing lines as possible.
Assume you have an optimal algorithm for this problem, and it places the next line(s) at distance a <= d from the last line. Say it places b lines. Our greedy algorithm will definitely place no more than b lines (since the first criterion is to place as few as possible), and if it places b lines it will place them at distance c with a <= c <= d, since it then places the lines as far as possible.
If the greedy algorithm did not do what the optimal algorithm did, it differed in one of the following ways:
It placed the same or fewer lines farther away. Suppose the optimal algorithm had gone on to place b' lines at distance a' away at the next step. Then these lines would be at distance a+a' and there would be b+b' lines in total. But the greedy algorithm can mimic the optimal algorithm in this case by placing b' lines at displacement a+a' by choosing c' = (a+a') - c. Since c > a and a' < d, c' < d and this is a legal placement.
It placed fewer lines closer together. This case is actually problematic. It is possible that this places k unnecessary lines, if any placement requires at least k lines and the farthest ones require more, and the arrangement of holes is chosen so that (e.g.) the distance it spans is a multiple of d.
So the greedy algorithm turns out not to work in case 2. However, it does in other cases. In particular, our observation in the first case is very useful: for any two placements (distance, lines) and (distance', lines'), if distance >= distance' and lines <= lines', the first placement is always to be preferred. This suggests the following algorithm:
PlaceLines(start, stop)
// if we are close enough to the other edge,
// don't place any more lines.
if start + d >= stop then return ([], 0)
// see how many lines we can place at distance
// d from the last placed lines. no need to
// ever place more lines than this
nmax = min_lines_at_distance(start + d)
// see how that selection pans out by recursively
// seeing how line placement works after choosing
// nmax lines at distance d from the last lines.
optimal = PlaceLines(start + d, stop)
optimal[0] = [d] . optimal[0]
optimal[1] = nmax + optimal[1]
// we only need to try fewer lines, never more
for n = 1 to nmax do
// find the max displacement a from the last placed
// lines where we can place n lines.
a = max_distance_for_lines(start, stop, n)
if a is undefined then continue
// see how that choice pans out by placing
// the rest of the lines
candidate = PlaceLines(start + a, stop)
candidate[0] = [a] . candidate[0]
candidate[1] = n + candidate[1]
// replace the last best placement with the
// one we just tried, if it turned out to be
// better than the last
if candidate[1] < optimal[1] then
optimal = candidate
// return the best placement we found
return optimal
This can be improved by memoization by putting results (seq, lines) into a cache indexed by (start, stop). That way, we can recognize when we are trying to compute assignments that may already have been evaluated. I would expect that we'd have this case a lot, regardless of whether you use a coarse or a fine discretization for problem instances.
I don't get into details about how max_lines_at_distance and max_distance_for_lines functions might work, but maybe a word on these.
The first tells you at a given displacement how many lines are required to span the geometry. If you have pixelated your geometry and colored holes black, this would mean looking at the row of cells at the indicated displacement, considering the contiguous black line segments, and determining from there how many lines that implies.
The second tells you, for a given candidate number of lines, the maximum distance from the current position at which that number of lines can be placed. You could make this better by having it tell you the maximum distance at which that number of lines, or fewer, could be placed. If you use this improvement, you could reverse the direction in which you're iterating n and:
if f(start, stop, x) = a and y < x, you only need to search up to a, not stop, from then on;
if f(start, stop, x) is undefined and y < x, you don't need to search any more.
Note that this function can be undefined if it is impossible to place n or fewer lines anywhere between start and stop.
Note also that you can memorize separately for these functions to save repeated lookups. You can precompute max_lines_at_distance for each row and store it in a cache for later. Then, max_distance_for_lines could be a loop that checks the cache back to front inside two bounds.

Algorithm for finding path combinations?

Imagine you have a dancing robot in n-dimensional euclidean space starting at origin P_0 = (0,0,...,0).
The robot can make m types of dance moves D_1, D_2, ..., D_m
D_i is an n-vector of integers (D_i_1, D_i_2, ..., D_i_n)
If the robot makes dance move i than its position changes by D_i:
P_{t+1} = P_t + D_i
The robot can make any of the dance moves as many times as he wants and in any order.
Let a k-dance be defined as a sequence of k dance moves.
Clearly there are m^k possible k-dances.
We are interested to know the set of possible end positions of a k-dance, and for each end position, how many k-dances end at that location.
One way to do this is as follows:
P0 = (0, 0, ..., 0);
S[0][P0] = 1
for I in 1 to k
for J in 1 to m
for P in S[I-1]
S[I][P + D_J] += S[I][P]
Now S[k][Q] will tell you how many k-dances end at position Q
Assume that n, m, |D_i| are small (less than 5) and k is less than 40.
Is there a faster way? Can we calculate S[k][Q] "directly" somehow with some sort of linear algebra related trick? or some other approach?
You could create an adjacency matrix that would contain dance-move transitions in your space (the part of it that's reachable in k moves, otherwise it would be infinite). Then, the P_0 row of n-th power of this matrix contains the S[k] values.
The matrix in question quickly gets enormous, something like (k*(max(D_i_j)-min(D_i_j)))^n (every dimension can be halved if Q is close to origin), but that's true for your S matrix as well
Since dance moves are interchangable you can assume that for a i < j the robot first makes all the D_i moves before the D_j moves, thus reducing the number of combinations to actually calculate.
If you keep track of the number of times each dance move was made calculating the total number of combinations should be easy.
Since the 1-dimensional problem is closely related to the subset sum problem, you could probably take a similar approach - find all of the combinations of dance vectors that add together to have the correct first coordinate with exactly k moves; then take that subset of combinations and check to see which of those have the right sum for the second, and take the subset which matches both and check it for the third, and so on.
In this way, you get to at least only have to perform a very simple addition for the extremely painful O(n^k) step. It will indeed find all of the vectors which will hit a given value.

Partition a set into k groups with minimum number of moves

You have a set of n objects for which integer positions are given. A group of objects is a set of objects at the same position (not necessarily all the objects at that position: there might be multiple groups at a single position). The objects can be moved to the left or right, and the goal is to move these objects so as to form k groups, and to do so with the minimum distance moved.
For example:
With initial positions at [4,4,7], and k = 3: the minimum cost is 0.
[4,4,7] and k = 2: minimum cost is 0
[1,2,5,7] and k = 2: minimum cost is 1 + 2 = 3
I've been trying to use a greedy approach (by calculating which move would be shortest) but that wouldn't work because every move involves two elements which could be moved either way. I haven't been able to formulate a dynamic programming approach as yet but I'm working on it.
This problem is a one-dimensional instance of the k-medians problem, which can be stated as follows. Given a set of points x_1...x_n, partition these points into k sets S_1...S_k and choose k locations y_1...y_k in a way that minimizes the sum over all x_i of |x_i - y_f(i)|, where y_f(i) is the location corresponding of the set to which x_i is assigned.
Due to the fact that the median is the population minimizer for absolute distance (i.e. L_1 norm), it follows that each location y_j will be the median of the elements x in the corresponding set S_j (hence the name k-medians). Since you are looking at integer values, there is the technicality that if S_j contains an even number of elements, the median might not be an integer, but in such cases choosing either the next integer above or below the median will give the same sum of absolute distances.
The standard heuristic for solving k-medians (and the related and more common k-means problem) is iterative, but this is not guaranteed to produce an optimal or even good solution. Solving the k-medians problem for general metric spaces is NP-hard, and finding efficient approximations for k-medians is an open research problem. Googling "k-medians approximation", for example, will lead to a bunch of papers giving approximation schemes.
http://www.cis.upenn.edu/~sudipto/mypapers/kmedian_jcss.pdf
http://graphics.stanford.edu/courses/cs468-06-winter/Papers/arr-clustering.pdf
In one dimension things become easier, and you can use a dynamic programming approach. A DP solution to the related one-dimensional k-means problem is described in this paper, and the source code in R is available here. See the paper for details, but the idea is essentially the same as what #SajalJain proposed, and can easily be adapted to solve the k-medians problem rather than k-means. For j<=k and m<=n let D(j,m) denote the cost of an optimal j-medians solution to x_1...x_m, where the x_i are assumed to be in sorted order. We have the recurrence
D(j,m) = min (D(j-1,q) + Cost(x_{q+1},...,x_m)
where q ranges from j-1 to m-1 and Cost is equal to the sum of absolute distances from the median. With a naive O(n) implementation of Cost, this would yield an O(n^3k) DP solution to the whole problem. However, this can be improved to O(n^2k) due to the fact that the Cost can be updated in constant time rather than computed from scratch every time, using the fact that, for a sorted sequence:
Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_1...x_h)-x_1 if h is odd
Cost(x_1,...,x_h) = Cost(x_2,...,x_h) + median(x_2...x_h)-x_1 if h is even
See the writeup for more details. Except for the fact that the update of the Cost function is different, the implementation will be the same for k-medians as for k-means.
http://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf
as I understand, the problems is:
we have n points on a line.
we want to place k position on the line. I call them destinations.
move each of n points to one of the k destinations so the sum of distances is minimum. I call this sum, total cost.
destinations can overlap.
An obvious fact is that for each point we should look for the nearest destinations on the left and the nearest destinations on the right and choose the nearest.
Another important fact is all destinations should be on the points. because we can move them on the line to right or to left to reach a point without increasing total distance.
By these facts consider following DP solution:
DP[i][j] means the minimum total cost needed for the first i point, when we can use only j destinations, and have to put a destination on the i-th point.
to calculate DP[i][j] fix the destination before the i-th point (we have i choice), and for each choice (for example k-th point) calculate the distance needed for points between the i-th point and the new point added (k-th point). add this with DP[k][j - 1] and find the minimum for all k.
the calculation of initial states (e.g. j = 1) and final answer is left as an exercise!
Task 0 - sort the position of the objects in non-decreasing order
Let us define 'center' as the position of the object where it is shifted to.
Now we have two observations;
For N positions the 'center' would be the position which is nearest to the mean of these N positions. Example, let 1,3,6,10 be the positions. Then mean = 5. Nearest position is 6. Hence the center for these elements is 6. This gives us the position with minimum cost of moving when all elements need to be grouped into 1 group.
Let N positions be grouped into K groups "optimally". When N+1 th object is added, then it will disturb only the K th group, i.e, first K-1 groups will remain unchanged.
From these observations, we build a dynamic programming approach.
Let Cost[i][k] and Center[i][k] be two 2D arrays.
Cost[i][k] = minimum cost when first 'i' objects are partitioned into 'k' groups
Center[i][k] stores the center of the 'i-th' object when Cost[i][k] is computed.
Let {L} be the elements from i-L,i-L+1,..i-1 which have the same center.
(Center[i-L][k] = Center[i-L+1][k] = ... = Center[i-1][k]) These are the only objects that need to be considered in the computation for i-th element (from observation 2)
Now
Cost[i][k] will be
min(Cost[i-1][k-1] , Cost[i-L-1][k-1] + computecost(i-L, i-L+1, ... ,i))
Update Center[i-L ... i][k]
computecost() can be found trivially by finding the center (from observation 1)
Time Complexity:
Sorting O(NlogN)
Total Cost Computation Matrix = Total elements * Computecost = O(NK * N)
Total = O(NlogN + N*NK) = O(N*NK)
Let's look at k=1.
For k=1 and n odd, all points should move to the center point. For k=1 and n even, all points should move to either of the center points or any spot between them. By 'center' I mean in terms of number of points to either side, i.e. the median.
You can see this because if you select a target spot, x, with more points to its right than it's left, then a new target 1 to the right of x would result in a cost reduction (unless there is exactly one more point to the right than the left and the target spot is a point, in which case n is even and the target is on/between the two center points).
If your points are already sorted, this is an O(1) operation. If not, I believe it's O(n) (via an order statistic algorithm).
Once you've found the spot that all points are moving to, it's O(n) to find the cost.
Thus regardless of whether the points are sorted or not, this is O(n).

Resources