Dijkstra Algorithm = SSSP - algorithm

What i have learnt , that dijkstra cannot work with negative edge weights . For that we have to use bellman ford .
Bellman fords works well with negative edge weights and negative cycles , which are not reachable from source otherwise, it will return a msg "Negative cycles exist".
But, this graph shown above works well with dijkstra , even though negative edge weights exist. So, how to know when to use dijkstra with negative edge weights ??
What is think , is that dijkstra can or cannot work with negative weight edges.
If negative cycle exists, then it will not work. But if not exists, it can or cannot work.
Am i right ?? plz guide me for this ??

Dijkstra's algorithm cannot work with negative edge weights. This is because once it marks a node as "visited", it assumes the shortest path to it has been found, and can not change, an invariant easily violated in graphs with negative edges (and no negative cycles):
A
/ \
7/ \2
/ \
B------>C
-6
Finding shortest paths with Dijkstra's algorithm starting from A will produce the wrong cost for C, 2.
The graph you posted doesn't work either: consider the shortest path starting from d to h. Dijkstra's on this graph will produce 4 for the path (d->g->h), whereas there's a cheaper path of 0 cost: d->a->b->c->h

Dijkstra cannot work with negative weight edges.
There is a algotithm named Johnson, which "re-weight" all the edges in the graph and finally make all the edges be positive. But the algorithm call the bellman ford algorithm and time complexity of it is O(V2logV + VE).
So the time complexity of Dijkstra + Johnson is not good. But if the graph can be processed, maybe you can use the algorithm in advance.
PS: I'm sorry for my poor English.

check the following code
import networkx as nx
g = nx.Graph()
g.add_edge(1, 2, weigbt=-10)
g.add_edge(2, 3, weight = -5)
g.add_edge(1, 3, weight =-6)
print(nx.single_source_dijkstra(g, 1, 3))
it doesn't matter if all of your edges are positive or negative, the Dijkstra SSSP will give you the same answer.
HOWEVER, it doesn't mean that for any graph with negative edge, the Dijkstra shortest path MAY give right answer in case of negative edge but that doesn't mean it WILL give right answer.

You are right, Dijkstra will work for negative weights. However it won't work if sum of weights in any cycle is negative.

Related

Backtrack after running Johnson algorithm

I have a question which I was asked in some past exams at my school and I can't find an answer to it.
Is it possible knowing the final matrix after running the Johnson Algorithm on a graph, to know if it previously had negative cycles or not? Why?
Johnson Algorithm
Johnson's Algorithm is a technique that is able to compute shortest paths on graphs. Which is able to handle negative weights on edges, as long as there does not exist a cycle with negative weight.
The algorithm consists of (from Wikipedia):
First, a new node q is added to the graph, connected by zero-weight edges to each of the other nodes.
Second, the Bellman–Ford algorithm is used, starting from the new vertex q, to find for each vertex v the minimum weight h(v) of a path from q to v. If this step detects a negative cycle, the algorithm is terminated.
Next the edges of the original graph are reweighted using the values computed by the Bellman–Ford algorithm: an edge from u to v, having length w(u, v), is given the new length w(u,v) + h(u) − h(v).
Finally, q is removed, and Dijkstra's algorithm is used to find the shortest paths from each node s to every other vertex in the reweighted graph.
If I understood your question correctly, which should have been as follows:
Is it possible knowing the final pair-wise distances matrix after running the Johnson Algorithm on a graph, to know if it originally had any negative-weight edges or not? Why?
As others commented here, we must first assume the graph has no negative weight cycles, since otherwise the Johnson algorithm halts and returns False (due to the internal Bellman-Form detection of negative weight cycles).
The answer then is that if any negative weight edge e = (u, v) exists in the graph, then the shortest weighted distance between u --> v cannot be > 0 (since at the worst case you can travel the negative edge e between those vertices).
Therefore, at least one of the edges had negative weight in the original graph iff any value in the final pair-wise distances is < 0
If the question is supposed to be interpreted as:
Is it possible, knowing the updated non-negative edge weights after running the Johnson Algorithm on a graph, to know if it originally had any negative-weight edges or not? Why?
Then no, you can't tell.
Running the Johnson algorithm on a graph that has only non-negative edge weights will leave the weights unchanged. This is because all of the shortest distances q -> v will be 0. Therefore, given the edge weights after running Johnson, the initial weights could have been exactly the same.

Dijkstra’s algorithm - DAG Shortest path with ONLY negative costs

I am looking for the shortest path between source (s) and sink (t) in an acyclic directed graph. The graph has topological order (temporal). All the edges have or negative or null cost.
Is it still possible to use Dijkstra algorithm?
The graph looks like this: graph example
Usually Dijkstra does not work with negative weights since the nodes are explored only once (with the assumption that the cost can only increase).
In this case, since I have only negative (or null cost), and the cost can only decrease, is ensured that the path is optimal if I explore the graph following the topological order?
Thank you
Yes, it will be optimal - but that's not Dijkstra's algorithm.
Dijkstra's algorithm specifies how to explore the nodes - according to their current weight. From the original article:
The shortest branch of set II is removed from this set and added to
set I. As a result one node is transferred from set B to set I .
What you are describing is a different solution, and it works:
D[source] = 0
D[v] = min {D[u] + w(u,v) | u in V}
Now, since you are following topological order, you can prove by induction the above formula is correct - since assuming the induction hypothesis is correct for all u that is explored before v, the conclusion that D[v] is also correct (since it won't be reopened) holds.
P.S. This proof does not even require the assumption of only negative weights, it works well if the weights are mixed, so the same solution holds.
What you are looking at is hence a longest path on a graph with positive weights (you just have to take the opposite of each value). This problem is in fact NP-hard for general graphs, but it becomes solvable in linear time if the graph is a Directed Acyclic Graph. A very good explanation is given here for example.

Dijkstra's Algorithm for Negative Weights

Okay, first of all I know Dijkstra does not work for negative weights and we can use Bellman-ford instead of it. But in a problem I was given it states that all the edges have weights from 0 to 1 (0 and 1 are not included). And the cost of the path is actually the product.
So what I was thinking is just take the log. Now all the edges are negative. Now I know Dijkstra won't work for negative weights but in this case all the edges are negative so can't we do something so that Dijkstra would work.
I though of multiplying all the weights by -1 but then the shortest path becomes the longest path.
So is there anyway I can avoid the Bellman-Ford algorithm in this case.
The exact question is: "Suppose for some application, the cost of a path is equal to the product all the weights of the edges in the path. How would you use Dijkstra's algorithm in this case? All the weights of the edges are from 0 to 1 (0 and 1 are not inclusive)."
If all the weights on the graph are in the range (0, 1), then there will always be a cycle whose weight is less that 1, and thus you will be stuck in this cycle for ever (every pass on the cycle reduces the total weight of the shortest path). Probably you have misunderstood the problem, and you either want to find the longest path, or you are not allowed to visit the same vertex twice. Anyway, in the first case dijkstra'a algorithm is definitely applicable, even without the log modification. And I am pretty sure the second case cannot be solved with polynomial complexity.
So you want to use a function, let's say F, that you will apply to the weights of the original graph and then with Dijkstra's algorithm you'll find the shortest product path. Let's also consider the following graph that we start from node A and where 0 < x < y < 1:
In the above graph F(x) must be smaller than F(y) for Dijkstra's algorithm to output correctly the shortest paths from A.
Now, let's take a slightly different graph that we start again from node A:
Then how Dijkstra's algorithm will work?
Since F(x) < F(y) then we will select node B at the next step. Then we'll visit the remaining node C. Dijkstra's algorithm will output that the shortest path from A to B is A -> B and the shortest path from A to C is A -> C.
But the shortest path from A to B is A -> C -> B with cost x * y < x.
This means we can't find a weight transformation function and expect Dijkstra's algorithm to work in every case.
You wrote:
I though of multiplying all the weights by -1 but then the shortest
path becomes the longest path.
To switch between the shortest and the longest path inverse the weights. So 1/3 will be 3, 5 will be 1/5 and so on.
If your graph has cycles, no shortest path algorithm will find an answer, because those cycles will always be "negative cycles", as Rontogiannis Aristofanis pointed out.
If your graph doesn't have cycles, you don't have to use Dijkstra at all.
If it is directed, it is a DAG and there are linear-time shortest path algorithms.
If it is undirected, it is a tree, and it's trivial to find shortest path in trees. And if your graph is directed, even without cycles, Dijkstra still won't work for the same reason it doesn't work for negative edge graph.
In all cases, Dijkstra is a terrible choice of algorithm for your problem.

Dijkstra vs Bellman- ford A Directed Graph which will give different result

I am trying to learn Graphs in which i found that to find shortest path from one node to other node we can use Dijkstra and Bellman-ford algorithm.
In which Dijkstra will not work for the Graph which contains negative weight edges.
While Brllman-ford can handle such Graph which contains negative weight edges.
My doubt is i tried many kind of Graphs which contains negative weight edge and applied Dijkstra and Bellman-ford both but in all the cases i found the same result i mean no difference, for negative weight edge also dijkstra is working fine.
May be my thought process or the way how i am solving is wrong so only i am getting correct answer for dikstra.
My question is can any one explain me a Graph which have negative edge and explain the different result for dijkstra and bellman-ford.
Djikstra algorithm to find the shortest path between two edges can be used only for graphs that have positive weights. To see the difference of answers that bellman-ford and djikstra gives when there is a negative edge weight, lets take a simple example
we have 3 nodes in the graph, A B C
A is connected to B edge weight 4
A is connected to C edge weight 2
B is connected to C edge weight -3
when djikstra is used to calculate shortest path between A and C, we get weight 2
but when bellman-ford is used to calculate the shortest path between A and C, the weight is 1
This is happening because of the fact that djikstra finalises the node which has the minimum edge weight, ignoring the fact that there could be path with less weight to that node (note that this could happen only when negative weights are present. with only positive weights this is not possible).
hope you understood the difference

Does Dijkstra's algorithm apply even if there is only one negative weight edge?

Will Dijkstra's Algorithm work if the digraph has only one negative weight edge and does not contain negative weight cycles?
No. Dijkstra's algorithm is greedy. It assumes path weights are strictly increasing.
Consider the following graph. S→A→E is optimal, but the Dijkstra's will return S→B→E.
Not necessarily. In this earlier answer, I gave an example of a graph with no negative cycles and one negative edge where Dijkstra's algorithm doesn't produce the correct answer. Therefore, Dijkstra's algorithm doesn't always work in this case.
Hope this helps!
No. Dijkstra is greedy algorithm. Once it added an edge, it never looks back.
No. Consider the following simple counterexample, with just 3 nodes, S (start), A, and B.
w(S, A) = 1
w(S, B) = 2
w(B, A) = -2
The algorithm will fix the distance for A first (cost 1), but it is cheaper to go there via B (cost 0).
Since Dijkstra's algorithm is greedy, it won't work with negative weights. U need some other algorithm like Bellman-Ford Algorithm for this purpose.
But, if you still want to use Dijkstra's Algo, there is a known way. In this method, you need to reassign costs, so that all become positive.
Here it is:
Suppose there is an edge from u to v. And the cost of the edge is cost(u,v).
u(d(u))------>v(d(v))
Define:
new_cost(u,v) = cost(u,v) + d(u) - d(v)
This is guaranteed to be positive since,
d(v) < d(u) + cost(u,v)
Now, we can apply Dijkstra's algorithm normally, only difference being, in the cost of the new path, which will be (say the path is in between s' and t')
= original cost of the same path + d(s') - d(t')
You can not apply Dijkstra's algorithm directly to a graph with a negative edge as some of the other answers have correctly noted.
There is a way to reweigh the graph edges given that there are no negative cycles in the original graph. It's the same technique used in Johnson's algorithm where first you run one instance of Bellman-Ford's algorithm to get the weights h(v) for each vertex v. Then you modify each edge w(u,v) to w(u,v) + h(u) − h(v) which is guaranteed to be positive so you end up with a new graph with only positive edges on which you can run Dijkstra's algorithm.
Section XV. from the Coursera Algorithms class explains it much better than me.
The only issue with applying that technique for the single source shortest path problem is that reweighting with Bellman-Ford takes O(mn) time which is slower than Dijkstra's O(m log(n)). So you are better off just running Bellman-Ford for your original graph.
Dijkstra's algorithm will work with a single negative edge as long as you start from the node which has that negative edge as an outgoing edge.
By starting with the smallest valued edge of the graph, you can no longer decrease the total cost by considering other edge weights (Which is how Dijkstra's algorithm works)
No, Dijkstras Algorithm is well known to not work with negative weights.
In case you need negative weights use Bellman-Ford algorithm.
WHY Dijkstra Can Fail It's Simple
because the Shortest Path Should Be : distance(s, vi) ≤ distance(s, vk )
For Exemple we have this Graph :
A---->B with Cost 2 B--->C with Cost Minus 4 the condition was False Now because Distance from A to B > Distance B to C

Resources