Does A* algorithm work with negative edge weights? - algorithm

I was trying to figure out why the heuristic used in A* tree search needs to be admissible if A* has to be optimal. By tree search I mean that there is no explored set maintained by the algorithm.
While doing this, I ran into the question: Does A* work for negative edge weights?

The A* algorithm is basically Dijkstra’s algorithm with heuristics. And Dijkstra’s algorithm does not work with negative edge weights. So A* won’t work with negative edge weights neither.
If you’re looking for an algorithm that works with negative edge weights, take a look at the Bellman-Ford algorithm (but it doesn’t use heuristics).

This excellent article regarding Dijkstra's may prove helpful and provides a nice example about negative edges...
http://www.ics.uci.edu/~eppstein/161/960208.html

Related

Shortest path in a directed, weighted graph with set number of weights

Lets say there is a graph (V,E) that is directed and weighted.
The weights of every edge in the graph are 1 or 2 or 3.
What would be a quick and efficient algo to find the shortest path? Thanks in advance!!
Dijkstra's algorithm would likely still have near-optimal performance, and has the advantage of being fairly simple.
However, for a graph with small integer weights, you can use more complicated versions of the (fibonacci) heap used in Dijkstra that have better asymptotic performance. Specifically, consider this work by Mikkel Thorup which solves single-source shortest path in O(|E| + |V| log log |C|) where E is the set of edges, V is the set of vertices and C is the largest weight. In your case C is constant, which turns the asymptotic complexity into O(|E| + |V|).
Do note that this is mostly of theoretical interest, and is unlikely to give any significant speedup over a simpler algorithm.
There a list of algorithms for the Shortest path problem:
Dijkstra's algorithm
A* search algorithm
...etc
you can find a list in this Wikipedia page about Shortest path problem Algorithms
you can test and play with this online Dijkstra Shortest Path visualization.
a very interesting Pathfinding-Visualizer to see how some algorithms explore the research space to reach the goal is in github Pathfinding-Visualizer , this will give you a general idea on th differences between algorithms visually. Note: Pathfinding doesn't mean the shortest path; it's depend on the used algorithm.

Can Bellman-Ford algorithm be used to find shorthest path on a graph with only positive edges?

I know that Dijkstra's algorithm can be used only on positive lengths of edges, and Bellman-Ford can be used when the graph also has negative ones.
Suppose we have a graph with only positive edges, though. Will Bellman-Ford give the same results as Dijkstra?
Yes, it will give the same results. It will run slower, though, as it could also have been used for graphs with negative edges (subject to the absence of negative cycles). If you look at the proof of BF's correctness, there is no assumption there that some of the edges are negative.
I want to add something to Ami Tavory's answer. Bellman-ford's algorithm can be made a little bit faster if you can detect that on any pass, there is no node value update, then return from there. If there is no node update then it proves that every node traversal is complete.

Can we use dijkstra algorithm to find any cycles

Can we use Dijkstra's algorithm to find cycles???
Negative cycles
Positive cycles
If we can what, are the changes we have to do?
1) Dijkstra's doesn't work on graphs with negative edges because you can (possibly) find a minimum distance of negative infinity.
2) Um, you normally run it on graphs with cycles (otherwise, you might as well be traversing a tree), so it can handle them just fine.
If your real question is just about finding cycles, look at Finding all cycles in graph
No We cant use Dijkstra algorithm if negative cycles exist as the algorithm works on the shortest path and for such graphs it is undefined.Once you get to a negative cycle, you can bring the cost of your "shortest path" as low as you wish by following the negative cycle multiple times.
This type of restriction is applicable to all sort of algorithms to find shortest path in a graph and this is the same reason that prohibits all negative edges in Dijkstra.
You may modify Dijkstra to find the cycles in the graph but i do not think it is the best practice.
Rather you can possibility Use:
Tarjan's strongly connected components algorithm(Time complexity -O(|E| + |V|))
or Kosaraju's algorithm (uses DFS and is a linear time alogoritham)
or you may follow this link for better idea:
https://en.wikipedia.org/wiki/Strongly_connected_component
Hope I answered your question.

Bellman-Ford vs Dijkstra: Under what circumstances is Bellman-Ford better?

After a lot of Googling, I've found that most sources say that the Dijkstra algorithm is "more efficient" than the Bellman-Ford algorithm. But under what circumstances is the Bellman-Ford algorithm better than the Dijkstra algorithm?
I know "better" is a broad statement, so specifically I mean in terms of speed and also space if that applies. Surely there is some situation in which the Bellman-Ford approach is better than the Dijkstra approach.
Bellman-Ford algorithm is a single-source shortest path algorithm, so when you have negative edge weight then it can detect negative cycles in a graph.
The only difference between the two is that Bellman-Ford is also capable of handling negative weights whereas Dijkstra Algorithm can only handle positives.
From wiki
However, Dijkstra's algorithm greedily selects the minimum-weight node
that has not yet been processed, and performs this relaxation process
on all of its outgoing edges; in contrast, the Bellman–Ford algorithm
simply relaxes all the edges, and does this |V | − 1 times, where |V |
is the number of vertices in the graph. In each of these repetitions,
the number of vertices with correctly calculated distances grows, from
which it follows that eventually all vertices will have their correct
distances. This method allows the Bellman–Ford algorithm to be applied
to a wider class of inputs than Dijkstra.
Dijkstra is however generally considered better in the absence of negative weight edges, as a typical binary heap priority queue implementation has O((|E|+|V|)log|V|) time complexity [A Fibonacci heap priority queue gives O(|V|log|V| + |E|)], while the Bellman-Ford algorithm has O(|V||E|) complexity
As already stated in the chosen answer, Bellman-Ford performs the check on all the vertices, Dijkstra only on the one with the best distance calculated so far. Again already noted, this improves the complexity of the Dijkstra approach, however it requires to compare all the vertices to find out the minimum distance value. Being this not necessary in the Bellman-Ford, it is easier to implement in a distributed environment. That's why it is used in Distance Vector routing protocols (e.g., RIP and IGRP), where mostly local information is used. To use Dijkstra in routing protocols, instead, it is necessary first to distribute the entire topology, and this is what happens in Link State protocols, such as OSPF and ISIS.
There are 4 major difference among them I know:-
1. bellman time complexity is O(VE) and Dijkstra Algo has O(ElogV)in case of maxheap is used.
Bellman does relaxation for n-1 times and Dijkstra Algo only 1 time.
Bellman can handle negative weights but Dijkstra Algo can't.
Bellman visit a vertex more then once but Dijkstra Algo only once.
The only difference is that Dijkstra's algorithm cannot handle negative edge weights which Bellman-ford handles.And bellman-ford also tells us whether the graph contains negative cycle.
If graph doesn't contain negative edges then Dijkstra's is always better.
An efficient alternative for Bellman-ford is Directed Acyclic Graph (DAG) which uses topological sorting.
http://www.geeksforgeeks.org/shortest-path-for-directed-acyclic-graphs/
Dijkstra Algo
Dijkstra algo is not capable to differentiate between Negative edge weight cycle is present in graph or not
1. Positive edge weight:- Dijkstra always PASS if all edge weight in a graph is positive
2. Negative edge wt. and No -ve edge wt. cycle:- Dijkstra always PASS even if we have some edges weight as Negative but NO cycle/loop in graph having negative edge weight.
[i.e No Negative edge weight cycle is present]
3. Negative edge wt. and -ve edge wt. cycle:- Dijkstra may PASS/FAIL even if we have some edges weight as negative along with cycle/loop in graph having negative edge weight.
In a normal introduction to algorithm class, you will learn that the only difference between Dijkstra and Bell-man Ford, is that the latter works for negative edges at the cost of more computation time. The discussion on time complexity is already give in the accepted answer.
However I want to emphasize and add a bit more to #Halberdier's answer that in a distributed system, Bellman-Ford is implemented EVEN WHEN ALL EDGES ARE Positive. This is because in a Bellman-Ford algorithm, the entity S does not need to know every weight of every edge in the graph to compute the shortest distance to T - it only needs to know the shortest distance for all neighbors of S to T, plus the weight of S to all its neighbors.
A typical application of such algorithm is in Computer Networking, where you need to find the shortest route between two routers. Dijkstra is implemented in a centralized manner called link state Routing, while
Bellman-Ford allows each router to update themselves asynchronously, called distance-vector routing.
I believe no one explains better than Jim Kurose, the author of <Computer Network, a top-down approach>. See his youtube videos below.
Link State routing:
https://www.youtube.com/watch?v=bdh2kfgxVuw&list=TLPQMTIwNjIwMjLtHllygYsxMg&index=3
Distance Vector routing:
https://www.youtube.com/watch?v=jJU2AVX6gpU&list=TLPQMTIwNjIwMjLtHllygYsxMg&index=4
Bellman Ford’s Algorithm
Dijkstra’s Algorithm
Bellman Ford’s Algorithm works when there is a negative weight edge, it also detects the negative weight cycle.
Dijkstra’s Algorithm may or may not work when there is a negative weight edge. But will definitely not work when there is a negative weight cycle.
The result contains the vertices which contain the information about the other vertices they are connected to.
The result contains the vertices containing whole information about the network, not only the vertices they are connected to.
It can easily be implemented in a distributed way.
It can not be implemented easily in a distributed way.
It is more time-consuming than Dijkstra’s algorithm. Its time complexity is O(VE).
It is less time-consuming. The time complexity is O(E logV).
Dynamic Programming approach is taken to implement the algorithm.
Greedy approach is taken to implement the algorithm.
Bellman Ford’s Algorithm has more overheads than Dijkstra’s Algorithm.
Dijkstra’s Algorithm has less overheads than Bellman Ford’s Algorithm.
Bellman Ford’s Algorithm has less scalability than Dijkstra’s Algorithm.
Dijkstra’s Algorithm has more scalability than Bellman Ford’s Algorithm.
Source 1
I do not agree completely, difference is in implementation and complexity, Dijsktra's algorithm is faster (O(n^2)) but difficult to implement, while Bellman Ford complexity is O(n^3) but is easier to implement.

Why use Dijkstra's algorithm instead of Best (Cheapest) First Search?

From what I have read so far. The Best First Search seems faster in terms of finding the shortest path to the goal because Dijkstra's algorithm has to relax all the nodes as it traverses the graph. What makes Dijkstra's algorithm better than Best First Search?
EDIT: Your edit clarifies you are interested in Best-First Search, and not BFS.
Best-First Search is actually an informed algorithm, which expands the most promising node first. Very similar to the well known A* algorithm (actually A* is a specific best-first search algorithm).
Dijkstra is uninformed algorithm - it should be used when you have no knowledge on the graph, and cannot estimate the distance from each node to the target.
Note that A* (which is a s best-first search) decays into Dijkstra's algorithm when you use heuristic function h(v) = 0 for each v.
In addition, Best First Search is not optimal [not guaranteed to find the shortest path], and also A*, if you do not use an admissible heuristic function, while Dijkstra's algorithm is always optimal, since it does not relay on any heuristic.
Conclusion: Best-First Search should be prefered over dijkstra when you have some knowledge on the graph, and can estimate a distance from target. If you don't - an uninformed Best-First Search that uses h(v) = 0, and relays only on already explored vertices, decays into Dijkstra's algorithm.
Also, if optimality is important - Dijkstra's Algorithm always fit, while a best-first search algorithm (A* specifically) can be used only if an appropriate heuristic function is available.
Original answer - answering why to chose Dijkstra over BFS:
BFS fails when it comes to weighted graphs.
Example:
A
/ \
1 5
/ \
B----1----C
In here: w(A,B) = w(B,C) = 1, w(A,C) = 5.
BFS from A will return A->C as the shortest path, but for the weighted graph, it is a path of weight 5!!! while the shortest path is of weight 2: A->B->C.
Dijkstra's algorithm will not make this mistake, and return the shortest weighted path.
If your graph is unweighted - BFS is both optimal and complete - and should usually be prefered over dijkstra - both because it is simpler and faster (at least asymptotically speaking).
Normally Best First Search algorithms in path finding, searching for path between two given nodes: Source and Sink, but Dijkstra's algorithm finds path between source and all other nodes. So you can't compare them. Also Dijkstra itself is kind of Best First Search (variation of A*) means you can't say it's not Best First Search. Also normal Best First Search Algorithms are using heuristics and they're not guarantee about correctness, Finally in weighted case normally their running time depends on weights, but Dijkstra's algorithm just depend to graph size.
BFS is good for finding shortest path from source to a vertex in case where all edges have same weight i.e. to find minimum no of edges from source to a vertex.
While Dikjstra holds good for weighted graphs

Resources