In the Johnson algorithm, it uses Bellman-Ford to convert graphs with negative edge weights(no negative cycles) into a graph with the same shortest paths but all the edge weights being non-negative - in O(mn) time.
Suppose we are given a DAG. How could we use an alternative method to convert the DAG into another graph with the same shortest paths, however in linear time as opposed to the previous O(mn) time.
I'm assuming we could modify Bellman-Ford during execution of the Johnson algorithm, however I'm unsure how to make it linear. Essentially, how could we figure out a way to reweight all edges in a graph to be non-negative in linear O(n) time?
Related
Given a weighted directed graph with n vertices where edge weights are integers (positive, zero, or negative), determining whether there are paths of arbitrarily large weight can be performed in time -
O(n)
O(n.log(n)) but not O(n)
O(n^1.5) but not O(nlogn)
O(n^3) but not O(n^1.5)
O(2n) but not O(n^3)
I'm not understanding what algorithm to use as finding the longest path is a NP Hard problem. Though, the answer given is O(n^3)
Briefly, you have to negate weights and then run the Floyd-Warshall algorithm. It takes O(n^3).
As mentioned here,
The graphs must be acyclic, otherwise paths can have
arbitrarily large weights. We can find longest paths just by negating all of the
edge weights, and then using a shortest path algorithm. Unfortunately, Dijk
stra’s algorithm does not work if edges are allowed to have negative weights.
However, the Floyd-Warshall algorithm does work, as long as there are no
negative weight cycles, and so it can be used to find longest weight paths in
acyclic graphs.
I was reading Introduction To Algorithms 3rd Edition. There are 3 methods given to solve the problem. My inquiry is about two of them.
The one with no name
The algorithm starts by topologically sorting the dag (see Section 22.4) to impose a linear ordering on the vertices. If the dag contains a path from vertex u to vertex v, then u precedes v in the topological sort. We make just one pass over the vertices in the topologically sorted order. As we process each vertex, we relax each edge that leaves the vertex.
Dijkstra's Algorithm
This is quite well known
As far as the book shows, time complexity of without name one is O(V+E) but of Dijstra's is O(ElogV). We cannot use Dijkstra's on negative weight but we can use the other. What are the advantages of using Dijkstra's Algorithm except it can be used in cyclic ones?
Because the first algorithm you give only works on acyclic graphs, whereas Dijkstra runs on graph with non-negative weight.
The limitations are not the same.
In real-world, many applications can be modelled as graphs with non-negative weights, that's why Dijkstra is so used. Plus, it is very simple to implement. The complexity of Dijkstra is higher because it relies on priority queue, but this does not mean it takes necessarily more time to execute. (nlog(n) time is not that bad, because log(n) is a relatively small number: log(10^80) = 266)
However, this stand for sparse graphs (low density of edges). For dense graphs, other algorithms may be more efficient.
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.
I know Bellman Ford algorithm works well with negative weighted Graph, But I've developed a code of Dijkstra Algorithm that works very well. But it fails when I insert negative weighted edges. Any Solution?
I think we can't do that, as Dijkstra algorithm will not find a final way to reach at destination vertex because it may get stuck in loops, it is not made for negative weighted graphs, you should go for bellman ford algorithm
Actually, it is possible in a special case. Dijkstra algorithm will fail, if there is an edge of a negative length. However, if all edges are of negative length, then you may inverse the lengths of all edges and use the algorithm to find the longest path between two vertices of the graph (the path will represent the shortest path in the original graph).
But in a general case, as you have stated, it is not possible to use Dijkstra. If there is no cycle of negative length, than you shall use Bellman-Ford algorithm. If you cannot guarantee that there no cycle of negative length, than the problem is NP-complete and there is no known polynomial algorithm.
As you stated, Bellman Ford is the algorithm of choice for finding the shortest path in a graph with negative weights. The issue with using Dijkstra's Algorithm in this scenario is that Dijkstra's assumes that all possible subpaths from s to t in a graph must be smaller than the goal subpath, which is not necessarily true when negative edge weights are added.
If all edge weights are positive, this guarantees that adding more edges to a path makes it longer. Knowing this, Dijkstra's algorithm will discard any paths that are longer than the shortest one it has found to some vertex since there is no chance of the long path becoming shorter than the short path.
However, this assumption is not true if there are negative edge weights since we could have an extremely long path P that we discarded, but somewhere down the road, P can pass through a very negative edge and become shorter than the shortest path you currently have. Therefore, we can't guarantee that a path we've found is the shortest at any stage in Dijkstra's algorithm, which the algorithm relies on.
For an undirected, unweighted graph, is there any difference in the time complexity of the algorithm to compute its average shortest path length vs, the complexity of the algorithm which computes the diameter of the graph, ie, the longest shortest path between two vertices?
According to Wikipedia, to calculate the diameter of the graph, you should first find the all-pairs shortest path. After calculating the all-pairs shortest path, both algorithms reduce down to a O(V^2) calculation so their complexities are the same.
I haven't read much literature on the subject but I suspect that the two are the same. However if there is a discrepancy, I'd say calculating the diameter of a graph might be asymptotically faster.
My algorithm for both would be to calculate all-pairs shortest path using Dijkstra's algorithm which runs in V*(E+V*log(V)). Then for the mean you would take the arithmetic average over all these values. I don't see a way you could speed this up.
However for calculating the diameter of a graph, there might be some clever tricks you can use to speed up this process. But as an upper bound, you can simply take the supremum over the all-pairs shortest path to get the diameter, which has the same run-time complexity as calculating the mean shortest path.
No there should not be any difference in the time complexity between the two.
You can find the longest path between two vertices by tweaking the shortest path algo.