So the major difference between Best-First Search (informed) and Uniform-Cost Search (uninformed) is that in BFS, we use a heuristic function to determine which node to go next. In UCS, we always take the lowest cost that is calculated from my initial state.
What is the heuristic function used in Best-First Search? It is mentioned everywhere that the heuristic function is h(n) = f(n), but what's f(n) exactly and how do I get its value if my "map" has many nodes and only the cost of the paths from one node to another?
A heuristic function is not a unique thing. It is a decision you make that heavily depends on the particular properties of the problem that is being solved. And even then you can choose between different approaches (functions). Often you'll try out how a chosen function influences the quality of the solutions found in sample cases, and test alternatives.
For example, if the graph is an Euclidean graph, where nodes represent coordinates in n-dimensional space, and the cost of an edge is its length (distance between connected nodes), then one possible heuristic could be the distance between source and target node.
The less you can assume about a graph -- the less you know about its properties --, the harder it will be to find a suitable heuristic function.
Related
I am doing a project to code the A* algorithm in the shortest path problem. In able to determine the shortest path using A* algorithm, I acknowledge that we have to get the heuristic value first. Do anyone know how to calculate and determine the heuristic value for each nodes? [i made up the map on my own so no heuristic values given]
A* and heuristic
A* always requires a heuristic, it is defined using heuristic values for distances. A* in principle is just the ordinary Dijkstra algorithm using heuristic guesses for the distances.
The heuristic function should run fast, in O(1) at query time. Otherwise you won't have much benefit from it. As heuristic you can select every function h for which:
h is admissible: h(u) <= dist(u, t) (never overestimate)
h is monotone: h(u) <= cost(u, v) + h(v) (triangle inequality)
There are however some heuristics that are frequently used in practice like:
Straight-line distance (as-the-crow-flies)
Landmark heuristic (pre-compute distances for all nodes to a set of selected nodes (landmarks))
Dependent on your application you might also find other heuristic functions useful.
Straight-line heuristic
The straight-line distance (or as-the-crow-flies) is straightforward and easy to compute. For two nodes v, u you know the exact location, i.e. Longitude and Latitude.
You then compute the straight-line distance by defining h as the Euclidean distance or if you want more precise results you don't ignore the fact that the earth is a sphere and use the Great-circle distance. Both methods run in O(1).
Landmark heuristic
Here you pre-select some important nodes in your graph. Ideally you always choose a node that is part of frequently used shortest-paths.
However that knowledge is often not available so you can just select nodes that are farthest to the other selected landmarks. You can do so by using greedy farthest selection (pick node which maximizes min_l dist(l, u) where l are already selected landmarks). Therefore you can do a Dijkstra from set which is very easy to implement. Just add multiple nodes at once into your Dijkstra starting queue (all current landmarks). Then you run the Dijkstra until all distances have been computed and pick the node with greatest shortest-path distance as next landmark. By that your landmarks are equally spread around the whole graph.
After selecting landmarks you pre-compute the distance from all landmarks to all other nodes and vice versa (from all nodes to all landmarks) and store them. Therefore just run a Dijkstra starting at a landmark until all distances have been computed.
The heuristic h for any node u, where v is the target node, then is defined as follows
h(u) = max_l(max(dist(u, l) - dist(v, l), dist(l, v) - dist(l, u)))
or for undirected graphs just
h(u) = max_l|dist(l, u) - dist(l, v)|
where max_l is a landmark which maximizes the argument.
After pre-computing said distances the method will obviously also run in O(1). However the pre-computation might take a minute or more but that should be no problem since you only need to compute it once and then never again at query time.
Note that you can also select the landmarks randomly which is faster but the results may vary in quality.
Comparison
Some time ago I created an image which compares some shortest-path computation algorithms I've implemented (PathWeaver at GitHub). Here's the image:
You see a query from top left to bottom right (inside the city). Marked are all nodes that where visited by the used algorithm. The less marks the faster the algorithm found the shortest-path.
The compared algorithms are
Ordinary Dijkstra (baseline, visits all nodes with that distance)
A* with straight-line heuristic (not a good estimate for road networks)
A* with landmarks (randomly computed) (good)
A* with landmarks (greedy farthest selected) (good)
Arc-Flags (okay)
Note that Arc-Flags is a different algorithm. It wants to have an area, like a rectangle around a city. It then selects all boundary nodes (nodes which are inside the rectangle but minimize distance to outside nodes). With those boundary nodes it performs a reversed Dijkstra (reverse all edges and then run Dijkstra). By that you efficiently pre-compute the shortest paths from all nodes to the boundary. Edges which are part of such a shortest path are then marked (arcs are flagged). At query time you run an ordinary Dijkstra but only consider marked edges. Therefore you follow shortest paths to the boundary.
This technique can be combined with others like A* and you can select many different rectangles, like all commonly searched cities.
There's also another algorithm I know (but never implemented though), it is called Contraction Hierarchies and it exploits the fact that you usually start at a small town road, then switch to a bigger road, then a highway and in the end vice versa until you reached your destination. Therefore it gives each edge a level and then first tries to as quickly as possible reach a high level and try to keep it as long as possible.
It therefore pre-computes shortcuts which are temporary edges that represent a shortest-path, like super-highways.
Bottom line
The right choice for a heuristic and also for an algorithm in general heavily depends on your model.
As seen for road networks, especially near smaller towns, the straight-line heuristic doesn't perform well since there often is no road that goes straight-line. Also for long distances you tend to first drive onto the highway which sometimes means driving into the opposite direction for some minutes.
However for games, where you often can move around where you like straight-line performs significantly better. But as soon as you introduce roads where you can travel faster (like by using a car) or if you have many obstacles like big mountains, it might get bad again.
Landmark heuristic performs well on most networks as it uses the true distance. However you have some pre-computation and trade some space since you need to hold all that pre-computed data.
Heuristic values are wholly domain-dependent, especially admissible ones (which A* requires). So, for example, finding the shortest path on a geographic map might involve a heuristic of the straight-line distance between two nodes, which could be pretty-well approximated by computing the Euclidean distance between the (latitude, longitude) of the two points.
This question already has answers here:
How does Dijkstra's Algorithm and A-Star compare?
(12 answers)
Closed 4 years ago.
I read this:
http://en.wikipedia.org/wiki/A*_search_algorithm
It says A* is faster than using dijkstra and uses best-first-search to speed things up.
If I need the algorithm to run in milliseconds, when does A* become the most prominent choice.
From what I understand it does not necessarily return the best results.
If I need quick results, is it better to pre-compute the paths? It may take megabytes of space to store them.
It says A* is faster than using dijkstra and uses best-first-search to
speed things up.
A* is basically an informed variation of Dijkstra.
A* is considered a "best first search" because it greedily chooses which vertex to explore next, according to the value of f(v) [f(v) = h(v) + g(v)] - where h is the heuristic and g is the cost so far.
Note that if you use a non informative heuristic function: h(v) = 0 for each v: you get that A* chooses which vertex to develop next according to the "so far cost" (g(v)) only, same as Dijkstra's algorithm - so if h(v) = 0, A* defaults to Dijkstra's Algorithm.
If I need the algorithm to run in milliseconds, when does A* become
the most prominent choice.
Not quite, it depends on a lot of things. If you have a decent heuristic function - from my personal experience, greedy best first (choosing according to the heuristic function alone) - is usually significantly faster than A* (but is not even near optimal).
From what I understand it does not necessarily return the best
results.
A* is both complete (finds a path if one exists) and optimal (always finds the shortest path) if you use an Admissible heuristic function. If your function is not admissible - all bets are off.
If I need quick results, is it better to pre-compute the paths? It may
take megabytes of space to store them.
This is a common optimization done on some problems, for example on the 15-puzzle problem, but it is more advanced. A path from point A to point B is called a Macro. Some paths are very useful and should be remembered. A Machine Learning component is added to the algorithm in order to speed things up by remembering these Macros.
Note that the path from point A to point B in here is usually not on the states graph - but in the problem itself (for example, how to move a square from the lowest line to the upper line...)
To speed things up:
If you have a heuristic and you find it too slow, and you want a quicker solution, even if not optimal - A* Epsilon is usually faster then A*, while giving you a bound on the optimality of the path (how close it is to being optimal).
Dijkstra is a special case for A* (when the heuristics is zero).
A* search:
It has two cost function.
g(n): same as Dijkstra. The real cost to reach a node n.
h(n): approximate cost from node n to goal node. It is a heuristic function. This heuristic function should never overestimate the cost. That means, the real cost to reach goal node from node n should be greater than or equal h(n). It is called admissible heuristic.
The total cost of each node is calculated by f(n)=g(n)+h(n)
Dijkstra's:
It has one cost function, which is real cost value from source to each node: f(n)=g(n)
It finds the shortest path from source to every other node by considering only real cost.
A* is just like Dijkstra, the only difference is that A* tries to look for a better path by using a heuristic function which gives priority to nodes that are supposed to be better than others while Dijkstra's just explore all possible paths.
Its optimality depends on the heuristic function used, so yes it can return a non optimal result because of this and at the same time better the heuristic for your specific layout, and better will be the results (and possibly the speed).
It is meant to be faster than Dijkstra even if it requires more memory and more operations per node since it explores a lot less nodes and the gain is good in any case.
Precomputing the paths could be the only way if you need realtime results and the graph is quite large, but usually you wish to pathfind the route less frequently (I'm assuming you want to calculate it often).
These algorithems can be used in pathfinding and graph traversal, the process of plotting an efficiently directed path between multiple points, called nodes.
Formula for a* is f =g + h., g means actual cost and h means heuristic cost.
formula for Dijktras is f = g. there is no heuristic cost. when we are using a* and if heuristic cost is 0 then it'll equal to Dijktras algorithem.
Short answer:
A* uses heuristics to optimize the search. That is, you are able to define a function that to some degree can estimate the cost from one node to the target. This is particulary useful when you are searching for a path on a geographical representation (map) where you can, for instance, guess the distance to the target from a given graph node. Hence, typically A* is used for path finding in games etc. Where Djikstra is used in more generic cases.
No, A* won't always give the best path.
If heuristic is the "geographical" distance, the following example might give the non optimal path.
[airport] - [road] - [start] -> [road] -> [road] -> [road] -> [road] -> [target] - [airport]
|----------------------------------------------------------------|
I'm in the process of writing an application to suggest circular routes over OpenStreetMap data subject to some constraints (the Orienteering Problem). In the innermost loop of the algorithm I'm trialling is a requirement to find the lowest cost path between two given points. Given the layout of the graph (basically Euclidean), the A star algorithm seems to be likely to produce results in the fastest time given the graph. However as well as distances on my edges (representing actual distances on the map), I also have a series of weights (currently scaled from 0.0, least desirable to 1.0, most desirable) indicating how desirable the particular edge (road/path/etc) is, calculated according to some metrics I've devised for my application.
I would like to modify my distances based on these weights. I am aware that the standard A star heuristic relies on the true cost of the path being at least as great as the estimate (based on a euclidean distance between the points). So my first thought was to come up with a scheme where the minimum edge distance is the real distance (for weight 1.0) and the distance is increased as the weight decreases (for instance quadrupling the distance for weight 0.0). Does this seem a sensible approach, or is there a better standard technique for fast routing under these circumstances?
I believe your approach is the most sane. Apparently I'm working on a similar problem, and I decided to use exactly the same strategy.
The A* algorithm doesn't necessarily rely on "true distances". It's not even about distances, you actually may minimize other physical quantity - the heuristic function should have the same physical units.
For instance, my problem is to minimize the path time, whereas the velocity at any given point depends on the location, time, and the chosen direction. My heuristic function is the rough distance (my problem is on the Earth surface, calculating the great circle distance is somewhat pricey) divided by the maximum allowed velocity. That is, it has units of time, and it's interpreted as the most optimistic time to reach the finishing point from the given location.
The relevant question is: "what do you actually want to minimize?". You need to end up with a single "modified distance", so that your pathfinding algorithm can pick the smallest one.
The continued usefulness of the A* algorithm depends on exactly how you integrate "desirability" into your routing distance. A* requires an "admissible heuristic" which is optimistic: the heuristic estimate for your "modified distance" must not exceed the actual "modified distance" (otherwise, the path it finds may not actually be optimal...). One way to ensure that is to make sure that the modified distance is always larger than the original, Euclidean distance for any given step; then, any A* heuristic admissible to minimize the Euclidean distance will also be admissible to minimize the modified distance.
For example, if you compute modified_distance = euclidean_distance / desirability_rating (for 0<desirability_rating<=1), your modified_distance will never be smaller than the euclidean_distance: whatever A* heuristic you were using for your unweighted paths will still be optimistic, so it will be usable for A*. (although, in regions where every path is undesirable, a highly over-optimistic A* heuristic may not improve performance as much as you would like...)
Fast(er) routing can be done with A*. In my own project I see a boost of approx. 4 times faster compared to dijkstra - so, even faster then bidirectional dijkstra.
But there are a lot more technics to improve query speed - e.g. introducing shortcuts and running A* on that graph. Here is a more detailed answer.
I am trying to find a optimal solution for the following problem
The numbers denoted inside each node are represented as (x,y).
The adjacent nodes to a node always have a y value that is (current nodes y value +1).
There is a cost of 1 for a change in the x value when we go from one node to its adjacent
There is no cost for going from node to its adjacent, if there is no change in the value of x.
No 2 nodes with the same y value are considered adjacent.
The optimal solution is the one with the lowest cost, I'm thinking of using A* path finding algorithm for finding an optimal solution.
My question, Is A* a good choice for the this kind of problems, or should i look at any other algorithm, and also i was thinking of using recursive method to calculate the Heuristic cost, but i get the feeling that it is not a good idea.
This is the example of how I'm thinking the heuristic function will be like this
The heuristic weight of a node = Min(heuristic weight of it's child nodes)
The same goes for the child nodes too.
But as far as my knowledge goes, heuristic is meant to be an approximate, so I think I'm going in the wrong direction as far as the heuristic function is concerned
A* guarantees to find the lowest cost path in a graph with nonnegative edge path costs, provided that you use an appropriate heuristic. What makes a heuristic function appropriate?
First, it must be admissible, i. e. it should, for any node, produce either an underestimate or a correct estimate for the cost of the cheapest path from that node to any of goal nodes. This means the heuristic should never overestimate the cost to get from the node to the goal.
Note that if your heuristic computes the estimate cost of 0 for every node, then A* just turns into breadth-first exhaustive search. So h(n)=0 is still an admissible heuristic, only the worst possible one. So, of all admissible heuristics, the tighter one estimates the cost to the goal, the better it is.
Second, it must be cheap to compute. It should be certainly O(1), and should preferably look at the current node alone. Recursively evaluating the cost as you propose will make your search significantly slower, not faster!
The question of A* applicability is thus whether you can come up with a reasonably good heuristic. From your problem description, it is not clear whether you can easily come up with one.
Depending on the problem domain, A* may be very useful if requirements are relaxed. If heuristic becomes inadmissible, then you lose the guarantee of finding the best path. Depending on the degree of overestimation of the distance, hovewer, the solution might still be good enough (for problem specific definition of "good enough"). The advantage is that sometimes you can compute that "good enough" path much faster. In some cases, probabilistic estimate of heuristics works good (it can have additional constraints on it to stay in the admissible range).
So, in general, you have breadth-first search for tractable problems, next faster you have A* for tractable problems with admissible heuristic. If your problem is intractable for breadth-first exhaustive search and does not admit a heuristic, then your only option is to settle for a "good enough" suboptimal solution. Again, A* may still work with inadmissible heuristic here, or you should look at beam search varieties. The difference is that beam searches have a limit on the number of ways the graph is currently being explored, while A* limits them indirectly by choosing some subset of less costly ones. There are practical cases not solvable by A* even with relaxed admissbility, when difference in cost among different search path is slight. Beam search with its hard limit on the number of paths works more efficiently in such problems.
Seems like an overkill to use A* when something like Dijkstra's would work. Dijkstra's will only work on non-negative cost transitions which seems true in this example. If you can have negative cost transitions then Bellman-Ford should also work.
A-star is used to find the shortest path between a startnode and an endnode in a graph. What algorithm is used to solve something were the target state isn't specifically known and we instead only have a criteria for the target state?
For example, can a sudoku puzzle be solved with an Astar-like algorithm? We dont know how the endstate will look like (which number is where) but we do know the rules of sudoku, a criteria for a winning state. Therefore I have a startnode and just a criteria for the endnode, which algorithm to use?
A* requires a graph, a cost function for traversal of that graph, a heuristic as to whether a node in the graph is closer to the goal than another, and a test whether the goal is reached.
Searching a Sudoku solution space doesn't really have a traversal cost to minimize, only a global cost ( the number of unsolved squares ), so all traversals would be equal cost, so A* doesn't really help - any cell you could assign costs one move and moves you one closer to the goal, so A* would be no better than choosing the next step at random.
It might be possible to apply an A* search based on the estimated/measured cost of applying the different techniques at each point, which would then try to find a path through the solution space with the least computational cost. In that case the graph would not just be the solution states of the puzzle, but you'd be choosing between the techniques to apply at that point - you'd know an estimate of the cost of a transition, but not where that transition 'goes', except that if successful, it's one step closer to the goal.
Yes, A* can be used when a specific goal state cannot be identified. (Pete Kirkham's answer implies this, but doesn't emphasise it much.)
When a specific goal state can't be identified, it's sometimes harder to come up with a useful heuristic lower bound on the remaining cost needed to complete a partial solution -- and the efficiency of A* depends on choosing an effective heuristic. But it doesn't mean it can't be applied. Any problem that can be solved on a computer can be solved using a breadth-first search, plus an array of flags indicating whether a state has been seen before; which is the same as A* with a heuristic lower bound that is always zero. (Of course, this is not the most efficient algorithm for solving many problems.)
You dont have to know the exact target endstate. It all comes down to the heuristic function, when it returns 0 you could assume to have found (at least) one of the valid endstates.
So during the a*, instead of checking if current_node == target_node, check if current_node.h() returns 0. If so, it should be infinitely close and/or overlapping the goal/endstate.