I implemented the A* algorithm (actually a modification thereof...) to calculate wiring on a circuit board.
While it is fairly fast in finding a path, it takes painfully long (>100ms) to find no path.
From the outlines of the algorithm I have come across it is clear that it will terminate only when the queue of unvisited nodes is empty.
Are there any heuristics to terminate the search for a path early -- possibly when adding additional assumptions?
I would just define a max cost limit and terminate if no candidate+lowerBoundOfEstimatedCosts is still smaller than this limit.
On a circuit board I would think no path should be longer than 5 times the manhatten distance (just my guess)
An other idea:
Maybe determine if there is a path at all (with some kind of 'flood fill') might be a good idea. It avoids calculating heuristics for each point and therefore should be much faster than searching the hole pace by A*-Search.
In an multi-threaded environment you could run this in a second (maybe low priority) thread and terminate the A*-Search as soon as you fill-approach finds out that there is no path at all.
Related
I need to solve TSP for a large number of vertices(30-100) with good accuracy and adequate time(like 1-2 days). My graph can contain asymmetrical edges(g[i][j] not equal g[j][i]).
I tried greedy, little(maybe my bad, but that shows worse results than greedy), simple genetic algo(barely better than greedy) , dynamic for O(2^n*n) (fast out of memory).
Well, 30-100 is not really large number of vertices. Did you miss some zeroes? Or you are facing some special hard to solve cases like p43 from TSPLIB?
In any case, if you are looking for a good heuristic I used to use Ant Colony Optimization for Asymmetric TSP. It is easy to implement and providers quite good performance.
You might take a look at my old implementation: https://github.com/aligusnet/optimer/tree/master/src/heuristics/aco
If you can accept not an optimal, but "close to optimal" solution, I can suggest you to use "random traveling" algorithm. Idea of this algorithm - do not BFS/DFS search through entire combination tree, but search just random DFS-subtrees.
For example, you have vertices [A-Z], and you start point within [A]. Try 10000 attempts for each path (total 32 prefix), started from [A-B-...], [A-C-...] and so on, where [...] is randomly selected full-depth path through your graph, according your rules. Keep cost of appropriate paths within array, where cost is sum of costs from each prefix. Because of you use equal attempts to all "start prefixes", sum of minimal prefix will show you best step from [A]. Of course, this is not guarantee for optimal, but this is high probability to be so.
For example, sum of 10,000 attempts withing path [A-K] is lowest. Next step - accept first step [A-K], and again repeat algorithm, until you found the solution.
Here's the TSP source code of the OptaPlanner implementation, fwiw. It deals with datasets up to 10k visits pretty good when NearbySelection is activated (or up to 500 visits or so if it's not activated) - to go above 10k you'll need to activate Partitioned Search which comes at a trade-off.
It has asymmetric datasets (using OpenStreetMap data) in the import/belgium/road-time directory. It can't prove if it reaches the optimal solution or not. Usually termination is set on either a few minutes or on a few unimproved minutes.
Benchmarks showed that Late Acceptance has slightly better results than Simulated Annealing and Tabu Search, given a specific set of MoveSelectors configured, but your mileage may vary...
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)'.
Essentially, it is a depth-first search that stops at a certain depth or cost. For example, it may DFS all nodes within 10 edges from the source, then 20, then 30. The difference is that rather than starting the DFS from scratch after each iteration, I store the "perimeter" of the searched area (a list of nodes) when each iteration of the search reaches its limits.
On the next iteration, i loop through all nodes on the perimeter, performing a DFS from each node, again to a fixed depth/cost before stopping, again recording down the perimeter of the searched area for the next iteration to start from.
The reason I am doing this is because my graph (which is a tree) is split into a set of logical "chunks", each of which must be fully explored before its child-chunks can start being explored. There are a large number of nodes but only a small number of chunks; I am essentially doing a chunk-by-chunk BFS, which each individual chunk (comprising a large number of individual nodes) being fully explored by its own mini-DFS.
Now, I just completely made this up on the spot to solve my problem, and it does, but is there anything like this in the literature? I haven't managed to find anything, but I'm sure someone else has done this before, and properly analysed its performance, asymptotic behavior, disadvantages, bugs, etc.. In that case, I would want to know about it.
I do not now of a name for this mixed type. I have used something similar too, but I don't think it is used very frequently and has a name. Often, the other algorithms make more sense:
If you want to advance slowly in chunks, Why don't you use a BFS?
Often a DFS is preferred because there you get the full traces. Furthermore, doing an iterative deepening DFS is simpler then your algorithm, just twice as time consuming, and requires much less memory.
I'm implementing a bidirectional A* search (bidirectional as in the search is performed from both the origin and destination simultaneously, and when these two searches meet, I'll have my shortest path - at least with a bit of extra logic thrown in).
Does anyone have any experience with taking a unidirectional A* and bidirectionalising(!) it - what sort of performance gain can I expect? I'd reckoned on it more-or-less halving the search time, at a minimum - but may I see bigger gains that this? I'm using the algorithm to determine shortest routes on a road network - if that's in any way relevant (I've read about MS's "Reach" algorithm, but want to take baby-steps towards this rather than jumping straight in).
In the best possible case it'd run in O(b^(n/2)) instead of O(b^n), but that's only if you're lucky :)
(where b is your branching factor and n is the number of nodes a unidirectional A* would consider)
It all depends on how easily the two searches meet, if they find each other at a good halfway point early in the search you've done away with a lot of search time, but if they branch into wildly different directions you may end up with something slower than simple A* (because of all the extra bookkeeping)
You may want to try https://github.com/sroycode/tway
there is a benchmarking script that compares this with standard astar
( for NY city roads data it seems to give a 30% time benefit )
You may consider clustering as much more efficient booster. Also see this article
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.