Summary: A task for picking certain objects is given in the form of an ordered sequence (eg. to pick apple, banana, apple, apple, orange, order matters). The objects have to be preassigned to certain physical locations with all the pairwise distance being known and fixed. The question is how to efficiently find the best location assignment so that the total traveling distance is minimized.
What I Have Tried: I cannot map this problem to any other algos that I know. For example, Dijkstra is to find the path given the graph, Knapsack is to find the right combination which the order doesn't matter.
- I posted this question on Stackoverflow
- I wrote an article on my blog to describe the problem in more detail for your reference
- I wrote a script to demonstrate how to find the optimal position assignment in a brute force way for a small number of objects.
Right now, this is at a complexity I believe of O(n!) and will totally explode as we increase the number of different objects.
# task is a sequence of order picking
task = '1212103' # means first pick up obj1, then obj2, then obj1, ..etc.
result = []
for c in permutations(range(4), 4):
# c contains the positions for all objects
# (1, 0, 2, 3) means obj0 stored at pos1, obj1 stored at pos0, etc.
res = 0
for f,t in zip(task, task[1:]):
pos_f = c[int(f)]
pos_t = c[int(t)]
# abs(...) is one oversimplief way to calculating distance between two positions
# in a 1d space for demonstration purpose
res += abs(pos_f - pos_t)
result.append((c, res))
And the outputs are all the permutations and the total distance:
[((1, 2, 3, 0), 6), # optimal position assignment #1 the yields the shortest distance
((2, 1, 0, 3), 6), # optimal position assignment #2 the yields the shortest distance
((0, 2, 3, 1), 7),
((1, 3, 2, 0), 7),
((2, 0, 1, 3), 7),
((3, 1, 0, 2), 7),
((0, 1, 2, 3), 8),
((0, 3, 2, 1), 8),
((3, 0, 1, 2), 8),
((3, 2, 1, 0), 8),
((0, 2, 1, 3), 9),
((3, 1, 2, 0), 9),
((0, 1, 3, 2), 11),
((1, 0, 2, 3), 11),
((1, 2, 0, 3), 11),
((2, 1, 3, 0), 11),
((2, 3, 1, 0), 11),
((3, 2, 0, 1), 11),
((0, 3, 1, 2), 13),
((3, 0, 2, 1), 13),
((1, 0, 3, 2), 14),
((2, 3, 0, 1), 14),
((1, 3, 0, 2), 15),
((2, 0, 3, 1), 15)]