Lecture 17: Dijkstra and Minimum Spanning Trees
COSC 311 Algorithms, Fall 2022
$
\def\compare{ {\mathrm{compare}} }
\def\swap{ {\mathrm{swap}} }
\def\sort{ {\mathrm{sort}} }
\def\insert{ {\mathrm{insert}} }
\def\true{ {\mathrm{true}} }
\def\false{ {\mathrm{false}} }
\def\BubbleSort{ {\mathrm{BubbleSort}} }
\def\SelectionSort{ {\mathrm{SelectionSort}} }
\def\Merge{ {\mathrm{Merge}} }
\def\MergeSort{ {\mathrm{MergeSort}} }
\def\QuickSort{ {\mathrm{QuickSort}} }
\def\Split{ {\mathrm{Split}} }
\def\Multiply{ {\mathrm{Multiply}} }
\def\Add{ {\mathrm{Add}} }
\def\cur{ {\mathrm{cur}} }
\def\gets{ {\leftarrow} }
$
Overview
- Dijkstra’s Algorithm Correctness
- Implementing Dijkstra
- Minimum Spanning Trees
Last Time: Weighted SSSP
Input.
- a weighted Graph $G = (V, E)$, edge weights $w$
- an initial vertex $u \in V$
- each vertex $v \in V$ has associated adjacency list
- list of $v$’s neighbors
- includes weight of edge from $v$ to each neighbor
Output.
Dijkstra’s Algorithm
- Initialize $d[u] = 0$ and $d[v] = \infty$ for all $v \neq u$
- Maintain set $S$ of finalized nodes, initially empty
- Process nodes. While $S \neq V$ do:
- find node $v$ in $V - S$ with minimal $d[v]$
- add $v$ to $S$
- for each neighbor $x$ of $v$
- update $d[x] \gets \min (d[x], d[v] + w(v, x))$
Correctness
- Initialize $d[u] \gets 0$ and $d[v] \gets \infty$ for all $v \neq u$
- Maintain set $S$ of finalized nodes, initially empty
- Process nodes: while $S \neq V$
- find node $v$ in $V - S$ with minimal $d[v]$
- add $v$ to $S$
- for each neighbor $x$ of $v$
- update $d[x] \gets \min (d[x], d[v] + w(v, x))$
Claim. For every vertex $v \in S$, $d[v]$ stores the correct (weighted) distance $d_w(u, v)$.
Proof of Claim
Claim. For every vertex $v \in S$, $d[v]$ stores the correct (weighted) distance $d_w(u, v)$.
Proof. Use induction on size of $S$. Set $k = $ size of $S$.
Base case $k = 1$. Only $u$ is added to $S$. Set $d[u] \gets 0$, which is correct answer.
Inductive Step I
Inductive hypothesis. When $S$ contains $k$ elements, $d[v]$ is correct for all vertices $v \in S$.
Consider next iteration of outer loop:
- $x$ has $d[x] = \min_{v \in S} (d[v] + w(v, x))$
Inductive Step II
Must show: $d[x] = d_w(u, x)$; argue by contradiction
- suppose $d[x] \neq d_w(u, x)$
- observe: there is a path from $u$ to $x$ of length $d[x]$
- $\implies d_w(u, x) < d[x]$
- $\implies$ there is a path $P$ from $u$ to $x$ of length $\ell < d[x]$
Shorter Path Illustration
Inductive Step III
Must show: $d[x] = d_w(u, x)$; argue by contradiction
- suppose $d[x] \neq d_w(u, x)$
- observe: there is a path from $u$ to $x$ of length $d[x]$
- $\implies d_w(u, x) < d[x]$
- $\implies$ there is a path $P$ from $u$ to $x$ of length $\ell < d[x]$
- $P$ must leave $S$ at some point $y$
- by definition of $x$, any path from $u$ to $y$ must be longer than $d[x]$
- $\implies w(P) \geq d[x]$, which contradicts $4$
Conclusion. $d[x] = d_w(u, x)$, as claimed.
Dijkstra Running Time?
$G$ has $n$ vertices, $m$ edges
Question. How many operations performed?
- Initialize $d[u] \gets 0$ and $d[v] \gets \infty$ for all $v \neq u$
- Maintain set $S$ of finalized nodes, initially empty
- Process nodes: while $S \neq V$
- find node $v$ in $V - S$ with minimal $d[v]$
- add $v$ to $S$
- for each neighbor $x$ of $v$
- update $d[x] \gets \min (d[x], d[v] + w(v, x))$
For Simplicity
Assume. Vertices are $1, 2, \ldots, n$
- $d$ is an array with $d[v] = $ distance from $u$ to $v$
- $\mathrm{final}$ is a Boolean array with $\mathrm{final}[v] = \mathrm{true}$ if $v$’s distance is finalized
- keep track of number of finalized vertices
- we’re done when $n$ vertices are finalized
Simple Implementation
For step
- find node $v$ in $V - S$ with minimal $d[v]$
use linear search
Question 1. What is running time of finding min?
Question 2. What is overall running time of Dijkstra?
Faster Implementation?
Since we need to access $v$ with minimum $d[v]$, store non-finalized vertices in a priority queue
- store elements with associated priorities
- add element with given priority
- remove element with smallest priority
Heap priority queue implementation
- supports these operations with running time $O(\log n)$
For Dijkstra:
- Store un-finalized vertices in priority queue
- priority of $v$ is $d[v]$
One Sublety, Two Solutions
Issue. Dijkstra decreases priority of vertices
Solution 1. Store duplicate vertices with each new distance
- will still find vertex $v$ with smallest $d[v]$
- if finalized vertex is returned, ignore it
- requires priority queue of size $m$ rather than $n$
Solution 2. Use more sophisticated priority queue that supports “decrease priority” operation
- can be implemented in $O(\log n)$ time
Conclusion
Dijkstra performs
- $n$ removals of vertices when they are finalized
- $2m$ distance updates
With efficient priority queues, these operations can each be performed in $O(\log n)$ time so…
Result. Dijkstra’s algorithm can be implemented to run in time $O(m \log n)$.
DPW in Königsberg
Winter is coming to Königsberg!
- Must prepare the bridges for ice
- Each bridge has an associated cost to de-ice
- Königsberg doesn’t have the budget to de-ice all bridges
- For public safety, must ensure that all landmasses are reachable from each other
Question. How to find the cheapest set of bridges to de-ice that maintain connectivity?
Picture
Graph Problem
Input:
- a weighted graph $G = (V, E)$ with edge weights $w$
Output:
The graph $T = (V, F)$ is called a minimum spanning tree of $G$
Example
Next Time
Greedy algorithms for the minimum spanning tree problem!