Calculate shortest path through a grocery store - algorithm

I'm trying to find a way to find the shortest path through a grocery store, visiting a list of locations (shopping list). The path should start at a specified start position and can end at multiple end positions (there are multiple checkout counters).
Also, I have some predefined constraints on the path, such as "item x on the shopping list needs to be the last, second last, or third last item on the path". There is a function that will return true or false for a given path.
Finally, this needs to be calculated with limited CPU power (on a smartphone) and within a second or so. If this isn't possible, then an approximation to the optimal path is also ok.
Is this possible? So far I think I need to start by calculating the distance between every item on the list using something like A* or Dijkstra's. After that, should I treat it like the traveling salesman problem? Because in my problem there is a specified start node, specified end nodes, and some constraints, which are not in the traveling salesman problem.

It seems like viewing it as a TSP problem makes it more difficult. Someone pointed out that grocery stories aren't that complicated. In the grocery stores I am familiar with (in the US), there aren't that many reasonable routes. Especially if you have a given starting point. I think a well thought-out heuristic will probably do the trick.
For example: I typically start at one end-- if it's a big trip I make sure I go through the frozen foods last, but it often doesn't matter and I'll start closest to where I enter the store. I generally walk around the outside, only going down individual aisles if I need something in that one. Once you go into an aisle, pick up everything in that one. With some aisles its better to drop into one end, grab the item, and go back to your starting point, and others you just commit to the whole aisle-- it's a function of the last item you need in that aisle and where you need to be next-- how to get out of the aisle depends on the next item needed-- it may or may not involve a backtrack-- but the computer can easily calculate the shortest path to the next items.
So I agree with the helpful hints of the other problems above, but maybe a less general algorithm will work. And will probably work better with limited resources. TSP tells us, however, you can't prove that it's the optimal approach but I suspect that's not really necessary...

Well, basically it is a traveling salesman problem, but with your requirements you limit the search space pretty well. If there are not too many locations, you could try to calculate all possible options, but if that is not feasible, you need to limit the search space even more.
You can make the search time limited so that you will return the shortest path you can find in 1 second, but that might not be the shortest of them all, but pretty short anyway.
You could also apply Greedy algorithm to find the next closest location, then using Backtracking select the next closest location etc.
Pseudo code for possible solution:
def find_shortest_path(current_path, best_path):
if time_limit()
return
if len(current_path) == NUM_LOCATIONS:
# destionation reached
if calc_len(current_path) < calc_len(best_path):
best_path = current_path
return
# You need to sort the possible locations well to maximize your chances of finding the
# the shortest solution
sort(possible_locations)
for location in possible_locations:
find_shortest_path(current_path + location, best_path)

Well, you could limit the search-space using information about the layout of the store. For instance, a typical store (at least here in Germany) has many shelves in it that can be considered to form lanes. In between there are orthogonal lanes that connect the shelf-lanes. Now you define the crossings to be the nodes and the lanes to be edges in a graph. The edges are labeled with all the items in the shelves of that section of lane. Now, even for a big store this graph would be pretty small. You would now have to find the shortest path that includes all the edge-labels (items) you need. This should be possible by using the greedy/backtracking approach Tuomas Pelkonen suggested.
This is just an idea, and I do not know if it really works, but maybe you can take it from here.

Only breadth first searching will make sure you don't "miss" a path through the store which is better than you're current "best" solution, but you need not search every node in the path. Nodes which are "obviously" longer than the current "best" solution may be expanded later.
This means you approach the problem like a "breath first" search, but alter the expansion of your nodes based on the current distance travelled. Some branches of the search tree will expand faster than others, because the manage to visit more nodes in the same amount of time.
So if node expansion is not truly breath-first, why do I keep using that word? Because after you do find a solution, you must still expand the current set of "considered nodes" until each one of those search paths exceed the solution. This avoids missing a path which has a lot of time consuming initial legs, but finishes faster than the current solution because the last step is lighting fast.

The requirement of a start node is fictitious. Using the TSP you'll end up with a tour where you can chose the start node that you want without altering the solution cost.
It's somewhat trickier when it comes to the counters: what you need is to solve the problem on a directed graph with some arcs missing (or, which is the same, where some arcs have a really high cost).
Starting with the complete directed graph you should modify the costs of the proper arcs in order to:
deny going from the items to the start node
deny going from the counters to the items
deny going from the start node to the counters
allow going from the counters to the start node at zero cost (this are only needed to close the path)
after having drawn the thing down, tell me if I missed something :)
HTH

Related

Graph search algorithm

I was blocked on the following question, can you please share your light on it?
one more: how to avoid the loop?
I believe the only sensible solution, assuming you don't have any information on the number of nodes in the network, is to take random left/right decisions at each node. Your route will form a random walk over the network and will eventually (after enough time steps) visit all nodes including the one with the hotel.
The number of steps required to get to the hotel will obviously depend on the size of the network but I believe it will be polynomial in the N, where N is the initial (but unknown) shortest path length between your starting point and the hotel. Without proof, I suggest teh average number of steps to solve for a network will scale as N^2.
Any deterministic path may run the risk of failing to visit one or more nodes.
Just found a counter example so the guess below is wrong.
I just tried a few examples - and did not try to explicitly construct a counter example - but it looks like alternating between going left and going right will visit all nodes without getting stuck in a loop. This may be the consequence of the graph being finite, 3-regular and planar. But I am very skeptic because I was unable to find this property mentioned anywhere and a handful of examples is far from a proof.

Unknown algorithm name

I have a matching problem, and have designed a method of solving it.
I need to know if an algorithm exists, if so the name, for the following situation, I have looked a lot, but cannot find anything. The closest I have come to is round robin, but thats not quite the same.
It is similar to some networking problems, but they generally don't get the most optimal route, they just settle for a good one. I need the most optimal.
This is a long read, and an unusual request for SO, but I cannot find a name for it anywhere.
The Problem
I have a pile of items.
Each item can be potentially connected to 1 or more other items.
Each item can only be paired once.
Each connection has a value.
I need to find what combination of pairs will result in the highest connection value.
My Solution
find all pairs for all items and store it in a map
take the first item and pair it with the first item in the maps value.
take the next item and pair it with the first unused item.
keep doing this until no more unused items exist.
save this combination or pairs total value.
change the last pair in the pair if possible.
compare to saved combination, if more save new combination
when the pair can no longer be changed, delete it and change the new last pair, find more possible pairs.
this keeps going until the combination list is reduced to size zero
The last saved combination is the best one.
(Fin)
This problem is basically just a maximum weighted matching.
For bipartite graphs, finding a maximum matching is easy. For arbitrary graphs, it's harder but still doable. Wikipedia suggests an algorithm by Edmonds called the Blossom Algorithm.
As for your algorithm, it's not clear exactly what you're doing, but it looks like a greedy assignment followed by hill climbing. I'm concerned that your algorithm isn't guaranteed to produce an optimal result. Have you actually proven this? How do you know it won't just get stuck in a local minima?
I believe you are looking for the Gale-Shapley algorithm, which solves the stable marriage problem.

Finding fastest cycle that gains at least x bonus points using backtracking algorithm

There's a map with points:
The green number next to each point is that point's ID and the red number is the bonus for that point. I have to find fastest cycle that starts and ends at the point #1 and that gains at least x (15 in this case) bonus points. I can use cities several times; however, I will gain bonus points only once.
I have to do this with the backtracking algorithm, but I don't really know where to start. I've stutied about it, but I can't see the connection between this and a backtracking.
The output would look like this:
(1,3,5,2,1) (11.813 length)
Backtracking is a technique applied to reduce the search space of a problem. So, you have a problem, you have a space with optimal and non-optimal solutions, and you have to pick up one optimal solution.
A simple strategy, in your problem, is to generate all the possible solutions. However, this solution would traverse the entire space of solutions, and, some times, being aware that no optimal solution will be found.
That's the main role of backtracking: you traverse the space of solutions and, when you reach a given point where you know no optimal answer will be achieved if the search continue on the same path, you can simply repent of the step taken, go back in the traversal, and select the step that comes right after the one you found to be helpless.
In your problem, since the nodes can be visited more than once, the idea is to maintain, for each vertex, a list of vertices sorted decreasingly by the distance from the vertex owner of the list.
Then, you can simply start in one of the vertices, and do the walk on the graph, vertex by vertex, always checking if the objective is still achievable, and backtracking in the solution whenever it's noticed that no solution will be possible from a certain point.
You can use a recursive backtracking algorithm to list all possible cycles and keep the best answer:
visitCycles(list<Int> cycleSoFar)
{
if cycle formed by closing (cycleSoFar) > best answer so far
{
best answer so far = cycle formed by closing (cycleSoFar)
}
if (cannot improve (cycleSoFar))
{
return
}
for each point that makes sense
{
add point to cycleSoFar
visitCycles(cycleSoFar)
remove point from cycleSoFar
}
}
To add a bit more detail:
1) A cycle is no good unless it has at least 15 bonus points. If it is any good, it is better than the best answer so far if it is shorter.
2) As you add more points to a cycle you only make it longer, not shorter. So if you have found a possible answer and cycleSoFar is already at least as long as that possible answer, then you cannot improve it and you might as well return.
3) Since you don't get any bonus points by reusing points already in the cycle, it doesn't make sense to try adding a point twice.
4) You may be able to speed up the program by iterating over "each point that makes sense" in a sensible order, for instance by choosing the closest point to the current point first. You might save time by pre-computing, for each point, a list of all the other points in ascending order of distance (or you might not - you might have to try different schemes by experiment).

Recursion to iteration - or optimization?

I've got an algorithm which searches for all possible paths between two nodes in graph, but I'm choosing path without repeating nodes and with my specified length of that path.
It is in ActionScript3 and I need to change my algorithm to iterative or to optimize it (if it's possible).
I have no idea how to do that and I'm not sure if changing to iterative will bring some better execution times of that function. Maybe it can't be optimized. I'm not sure.
Here is my function:
http://pastebin.com/nMN2kkpu
If someone could give some tips about how to solve that, that would be great.
For one thing, you could sort the edges by starting vertex. Then, iterating through a vertex' neighbours will be proportional to the number of neighbours of this vertex (while right now it's taking O(M), where M is the edge count for the whole graph).
If you relax the condition of not repeating a vertex, I'm certain the problem can be solved in better time.
If, however, you need that, I'm afraid there's no simple change that would make your code way faster. I can't guarantee on this, though.
Also, if I am correct, the code snippet tests if the edge is used already, not if the vertex is used. Another thing I noticed is that you don't stop the recursion once you've found such a path. Since in most* graphs, such a path will exist for reasonable values of length, I'd say if you need only one such path, you might be wasting a lot of CPU time after one such path is found.
*Most - to be read 'maybe most (IMO)'.

Algorithm for shortening a series of actions?

It's been awhile since my algorithms class in school, so forgive me if my terminology is not exact.
I have a series of actions that, when run, produces some desired state (it's basically a set of steps to reproduce a bug, but that doesn't matter for the sake of this question).
My goal is to find the shortest series of steps that still produces the desired state. Any given step might be unnecessary, so I'm trying to remove those as efficiently as possible.
I want to preserve the order of the steps (so I can remove steps, but not rearrange them).
The naive approach I'm taking is to take the entire series and try removing each action. If I successfully can remove one action (without altering the final state), I start back at the beginning of the series. This should be O(n^2) in the worst case.
I'm starting to play around with ways to make this more efficient, but I'm pretty sure this is a solved problem. Unfortunately, I'm not sure exactly what to Google - the series isn't really a "path," so I can't use path-shortening algorithms. Any help - even just giving me some terms to search - would be helpful.
Update: Several people have pointed out that even my naive algorithm won't find the shortest solution. This is a good point, so let me revise my question slightly: any ideas about approximate algorithms for the same problem? I'd rather have a short solution that's near the shortest solution quickly than take a very long time to guarantee the absolute shortest series. Thanks!
Your naive n^2 approach is not exactly correct; in the worst case you might have to look at all subsets (well actually the more accurate thing to say is that this problem might be NP-hard, which doesn't mean "might have to look at all subsets", but anyway...)
For example, suppose you are currently running steps 12345, and you start trying to remove each of them individually. Then you might find that you can't remove 1, you can remove 2 (so you remove it), then you look at 1345 and find that each of them is essential -- none can be removed. But it might turn out that actually, if you keep 2, then just "125" suffice.
If your family of sets that produce the given outcome is not monotone (i.e. if it doesn't have the property that if a certain set of actions work, then so will any superset), then you can prove that there is no way of finding the shortest sequence without looking at all subsets.
If you are making strickly no assumptions about the effect of each action and you want to strickly find the smallest subset, then you will need to try all possible subets of actions to find the shortest seuence.
The binary search method stated, would only be sufficient if a single step caused your desired state.
For the more general state, even removing a single action at a time would not necessarily give you the shortest sequence. This is the case if you consider pathological examples where actions may together cause no problem, but individually trigger your desired state.
Your problem seem reducable to a more general search problem, and the more assumptions you can create the smaller your search space will become.
Delta Debugging, A method for minimizing a set of failure inducing input, might be a good fit.
I've previously used Delta(minimizes "interesting" files, based on test for interestingness) to reduce a ~1000 line file to around 10 lines, for a bug report.
The most obvious thing that comes to mind is a binary search-inspired recursive division into halves, where you alternately leave out each half. If leaving out a half at any stage of the recursion still reproduces the end state, then leave it out; otherwise, put it back in and recurse on both halves of that half, etc.
Recursing on both halves means that it tries to eliminate large chunks before giving up and trying smaller chunks of those chunks. The running time will be O(n log(n)) in the worst case, but if you have a large n with a high likelihood of many irrelevant steps, it ought to win ahead of the O(n) approach of trying leaving out each step one at a time (but not restarting).
This algorithm will only find some minimal paths, though, it can't find smaller paths that may exist due to combinatorial inter-step effects (if the steps are indeed of that nature). Finding all of those will result in combinatorial explosion, though, unless you have more information about the steps with which to reason (such as dependencies).
You problem domain can be mapped to directional graph where you have states as nodes and steps as links , you want to find the shortest path in a graph , to do this a number of well known algorithms exists for example Dijkstra's or A*
Updated:
Let's think about simple case you have one step what leads from state A to state B this can be drawn as 2 nodes conected by a link. Now you have another step what leads from A to C and from C you havel step what leads to B. With this you have graph with 3 nodes and 3 links, a cost of reaching B from A it eather 2 (A-C-B) or 1 (A-B).
So you can see that cost function is actualy very simple you add 1 for every step you take to reach the goal.

Resources