layout | title | math | part |
---|---|---|---|
notes |
Greedy Algorithms Shortest Path |
true |
true |
Input:
- A weighted graph/digraph
- A source node(start)
- A destination node(end) Output:
- A shortest path through the graph from the source to the destination
- A weighted graph/digraph
- A source node(start) Output:
- A set of shortest paths through the graph from the source to every node in the graph
- Can be represented as a tree with the source as the node
Maintain a set of explored nodes
let
initialize
repeatedly:
- choose unexplored node
$$v\notin S$$ that minimises$$\pi(v)$$ where:
$$ \pi(v) = \min_{e = (u,v):u \in S}
$$
- add
$$v$$ to$$S$$ ,$$d[v]\leftarrow \pi(v)$$ - prev[v]
$$\leftarrow e$$
The shortest path can then be found by traversing from any point to the start by following prev
Prove:
For every node
$$u \in S$$ ,$$d[u]$$ is the shortest path$$s \rightarrow u$$
strategy: induction
base Case:
when
Inductive case:
Assume is true for
Let
A shortest path
Consider anther path
- let
$$e = (x,y)$$ be the first edge in$$P$$ that leaves$$S$$ - so
$$x \in S \land y \notin nS$$
- so
- let
$$P'$$ be the subpath of$$s \rightarrow x$$ - the length of
$$P \geq \pi(v)$$ as soon as it reaches y
when L determines the length of a path or edge
Efficient algorithm can be found by implementing some optimizations on the previous strategy.
For each unexplored node
Maintain
As elements are added to
Suppose
then:
Use a min-optimized priority queue to chose an unexplored node that minimises
graph <- graph to search
s <- start node
dist <- array of distances
prev <- array of previous nodes
//initialize start values
pq = priorityQueue()
for each vertex in graph{
dist[vertex] = INFINITY
prev[vertex] = UNDEFINED
}
dist[s] = 0;
for each vertex in graph{
pq.insert(s,dist[s]);
}
// calculate minimum path
while (pq.empty =false){
u = pq.removeMin();
for edge in graph.edgesFrom(u){
v = edge.goingTo()
if (dist[v] > dist[u]+edge.weight){
dist[v]=dist[u]+edge.weight
pq.decreaseKey(v,dist[v])
prev[v]=u
}
}
}
The shortest path for a node can be found by traversing prev from the node to the start
The time complexity fo the algorithm depends on the priority queue algorithm chosen and the ratio of edges to nodes.
For a dense graph $$ e $$ is $$ O(n^2)$$ (where decreaseKey
is
For a sparse graph $$ e $$ is $$ O(n)$$ then a heap based method is better as removeMin
is