Dijkstra ā
Dijkstraās greedy algorithm solves the single-source shortest-paths problem on a weighted, directed graph G=(V,E) for the case in which all edge weights are non-negative
- We assume that w(u,v)>=0 ā(u,v)āE
Data Structures ā
We find here a Priority Queue Q of vertices which have not been selected yet and have the key field d, the smaller, the more promising they are.
Dijkstraās algorithm also maintains a set S of vertices whose final shortest-path weights from the source s have already been determined.
Algorithm ā
- Initialization
- The algorithm repeatedly selects the vertex uā{V\S}S with the minimum shortest-path estimate (d)
- Adds u to S
- Relaxes all edges leaving u
- Stops when Q is empty
- Returns
- d, the vector containing the estimations
- GĻ, predecessor subgraph
Dijkstra(Graph G, Weight w, Vertex s)
INIT_SS(G, s)
Q = G.V
S = ā
while(Q != ā
):
u = EXTRACT_MIN(Q);
S = S āŖ {u};
for(v in Adj[u]): #Relax every leaving vertex.
RELAX(u, v, w(u,v));
return (d, GĻ);Dijkstra(Graph G, Weight w, Vertex s)
INIT_SS(G, s)
Q = G.V
S = ā
while(Q != ā
):
u = EXTRACT_MIN(Q);
S = S āŖ {u};
for(v in Adj[u]): #Relax every leaving vertex.
RELAX(u, v, w(u,v));
return (d, GĻ);Final Time Complexity: T(n) = O(m * log(n))
- Always ends because the while cycle extracts every time a vertex and the for cycle is always ending.
- When a graph is dense
m-->n^2, while when it is sparsem-->n
| Graph\Q | Binary Heap | Array |
|---|---|---|
| Dense | O(n^2*log(n) | O(n^2) |
| Sparse | O(n*log(n)) | O(n^2) |
1 - Complexity Demonstration ā
A) Q is an Array - Best for dense graph ā
Final Time Complexity: T(n) = O(n2) = O(n) + O(n2) + O(m)
- n < n**2
- m <= n**2
- Initialization: Ī(n)
- INIT_SS(): Ī(n)
- While block: O(n^2)
- WHILE * EXTRACT_MIN(): Ī(n)
- Unordered array, so the worst is to look through n elements.
- FOR RELAX(): O(m 1) = sum(out-deg(u), u in V) * T(1)
- Executes RELAX a number of times equal to the out-degree of the vertex
- WHILE * EXTRACT_MIN(): Ī(n)
B) Q is a binary heap - Best for sparse graph ā
Final Time Complexity: T(n) = O(m log(n)) = O(n) + O(n log(n)) + O(m * log(m))
- If the graph is connected, m*log(n)
1. Initialization: Ī(n)
2. While block: O(m * log(n))
1. WHILE EXTRACT_MIN(): Ī(n* log(n))
2. FOR RELAX(): O(m* log(n)) = sum(out-deg(u), u in V) * T(RELAX())1. Initialization: Ī(n)
2. While block: O(m * log(n))
1. WHILE EXTRACT_MIN(): Ī(n* log(n))
2. FOR RELAX(): O(m* log(n)) = sum(out-deg(u), u in V) * T(RELAX())
2 - Correctness Demonstration: Theorem of Dijkstra ā
Let G=(V,E, w) be a directed graph, with w a real-value function w:E-->R>=0, and sāV is the source vertex.
- w(u,v)>=0 ā(u,v)āE, all the edges weights are positive.
When Dijkstra's algorithm stops we have:
- āuāG : d[u] = Ī“(s,u)
- Necessarily, the distances will be equal to the estimates
- GĻ, the predecessor subgraph, is a shortest-path tree (by Lemma 24.17)
What we are saying is during the extraction of the vertex u from Q (uāV), the property d[u]=Ī“(s,u) stands true. How do we know this stands true until the algorithm stops?
We know that if the property stands true during extraction, since d[u] reached the inferior limit, it will not be changed afterwards.
Ad absurdum, let's say we have a vertex āuāV such that upon extraction d[u]!=Ī“(s,u). Furthermore, u is the first vertex where this happens.
Let's make some observations:
- u!=s, after INIT_SS():
sis the first vertex added to S, so S!=Ć before u is added to S- And if
u==sthen,d[s]!= Ī“(s,s), d[s]!= 0at that time, not possible by construction of INIT_SS.- It is not always true, if s is to be found on a negative cycle, d[s]=0 and Ī“(s,s)=-inf()
- But by hypothesis, all weights are positive
- There must exist at least one shortest-path p form s to u,
Ī“(s,u) < +inf()- Otherwise, d[u] = Ī“(s,u) = +inf() by no-path property, but the assumption
d[u] != Ī“(s,u)violates it, since d[u] will not change value from the initialization.
- Otherwise, d[u] = Ī“(s,u) = +inf() by no-path property, but the assumption
- p must include an edge (x,y) that crosses the cut (S, Q) such that xāS, yāQ (otherwise there is no path).
- Ī“(s,u) = Ī“(s,x) + w(x,y) + Ī“(y,u), by decomposition of distances
- d[x]=Ī“(s,x), by assumption
- xāS, while uāQ. It is still not the case for estimates to differ from the real distances.
- d[y]=Ī“(s,y), by the convergence property
- By extracting x, there has been a RELAX on (x,y) which updates d[y] to be exactly equal to the real distance
- d[u]<=d[y], by construction of Dijkstra and by assumption
- In the case we extract u from Q before y.
- Ī“(s,u)>=Ī“(s,y), by hypothesis of positive weights.
- y appears before u on a shortest-path from s to u
- In case of negative weights, in the path from s to u we could reach a weight inferior to the path from s to u.
- d[u]>=Ī“(s,u), by inferior limit
Let's consider all the pieces of the puzzle now:
- Ī“(s,u)<=d[u], By 3.6
- Ī“(s,u)<=d[u]<=d[y], By 3.4
- Ī“(s,u)<=d[u]<=Ī“(s,y), By 3.3
- Ī“(s,u)<=d[u]<=Ī“(s,y)<=Ī“(s,u), By 3.5
Trivially, d[u]=Ī“(s,u), which contradicts the absurd

Example ā

CPU Improvement ā
Exercises:
- What would happen if the algorithm extracts n-1 vertices?
- We execute the RELAX() even on edges that lead to vertices we have already extracted. What if did not consider those edges?
- We are given a directed graph G=(V,E) on which each edge (u,v) has an associated value r(u,v) which is a real number in the range 0<=r(u,v)<=1 that represents the reliability of a communication channel from vertex u to vertex. We interpret r(u,v) as the probability that the channel from u to will not fail, and we assume that these probabilities are independent. Give an efficient algorithm to find the most reliable path between two given vertices. (Solution Lesson 04/12/2022)
Problems ā
What to do if G has negative weights? There is nothing that ensures the algorithm is going to work properly 100% of the time
Conclusions ā
Best to be used when there are no negative weights nor negative cycles