1 Theory I Algorithm Design and Analysis (10 - Shortest paths in graphs) T. Lauer.
-
Upload
mercedes-hamlyn -
Category
Documents
-
view
226 -
download
1
Transcript of 1 Theory I Algorithm Design and Analysis (10 - Shortest paths in graphs) T. Lauer.
1
Theory I
Algorithm Design and Analysis
(10 - Shortest paths in graphs)
T. Lauer
2
Graphs
• Many problems can be modeled with graphs - navigation systems- networks- planning problems - …
• A frequent task occurring in optimization problems is
to find shortest paths in graphs.
3
Definition of a graph
Definition: A directed graph G = (V,E) (or: digraph) consists of a set
V = {1, 2, . . . , |V |} of vertices and a set E V x V of edges (or: arcs).
A pair (v, v’) E is called an edge (or arc) from v to v’.
Representation:
• Vertices are represented by dots (nodes).
• Edges are represented by connecting lines with an arrowhead pointing to
the destination vertex.
Restriction: Finite graphs, i.e. V
4
Example of a digraph
1
3
8
6
7
5
9
4
2
5
Adjacency matrix
• Graphs can be stored as adjacency matrices.
• A graph G = (V,E) is stored in a Boolean |V | x |V | matrix
AG = (aij), where 1 ≤ i ≤ |V |, 1 ≤ j ≤ |V | and
class Graph {
Graph(int n) {
this.numberOfNodes = n;
this.a = new boolean[n][n];
}
private int numberOfNodes;
private boolean[][] a;
}
if
if
Eji
Ejiaij ),(1
),(0
6
Example of an adjacency matrix
1 2 3 4 5 6 7 8 9
1 0 1 1 0 0 0 1 0 0
2 0 0 0 0 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0
4 0 0 0 0 0 1 0 0 0
5 0 0 0 1 0 0 0 0 0
6 1 0 0 0 1 1 0 0 0
7 0 0 0 0 1 0 0 0 0
8 0 0 0 0 0 0 0 0 0
9 0 0 0 0 0 0 0 1 0
8
9
12
3
6
7
5
4
7
Properties of adjacency matrices
• The memory requirement for storing a graph with vertex set V in an
adjacency matrix is Θ(|V |2).
• This memory requirement is independent of the number of edges
in the graph.
• Hence, adjacency matrices are not so efficient for graphs with a relatively
small number of edges.
• Because of the necessary initialization of the matrix or the consideration
of all matrix entries most algorithms take at least Ω(|V |2) computational
steps.
8
Adjacency lists
• Using adjacency lists, for each vertex we store a linear linked list of the
edges originating from this vertex.
• The vertices are maintained in a linear array of |V | initial pointers to these
lists.
• The i-th list contains one list element with key j for each destination vertex
of an edge.
• Adjacency lists support many operations very well, e.g. tracing edges in a
graph.
• On the other hand, some operations are not supported well, especially
insertion and deletion of vertices.
Eji ),(
9
An example
3
7
2
6 4 6 5 8
5
1
1 2 3 4 5 6 7 8 9
10
Implementation of adjacency lists
class graphAL{
graphAL(int n){
this.numberOfNodes = n;
this.edgeTo = new edge[n];
}
private int numberOfNodes;
private edge[] edgeTo;
}
class edge {
edge(int node, edge next){
this.node = node;
this.next = next;
}
int node;
edge next;
}
11
Adjacency lists
• Memory requirement: O(|V| + |E|)
• Adjacency lists support many operations very well, e.g. tracing edges in a
graph.
• On the other hand, some operations are not supported well, especially
insertion and deletion of vertices.Eji ),(
12
Doubly-connected edge list
• The missing dynamics of adjacency lists can be achieved by storing the
vertices in a doubly-connected list instead of an array of fixed length.
• Each element of this list contains three references: 2 to the neighboring
list elements and one to an edge list, just like an adjacency list.
• Each edge list is doubly connected; instead of a vertex number, each
edge list element contains a pointer to the respective element of the
vertex list.
13
Doubly-connected edge lists: example
1 2 3 4 5 6 7 8 9
14
Shortest paths in unweighted graphs
Definition: The single-source shortest-path problem is the task of finding, for
a graph G = (V,E) and a vertex v V, the shortest paths from v to all other
vertices in G.
Examples:
Graph g Shortest paths originating from vertex 1
1 2
1 3
1 7
1 7 5
1 7 5 4
1 7 5 4 6
8
9
12
3
6
7
5
4
15
Weighted graphs
• In a weighted graph each edge is labeled with a real number.
• These weights are interpreted as distances or cost of traversal.
• In the following we assume that these weights are non-negative, i.e.
that there is a mapping c : E R0+ assigning a weight to each edge.
1
3
8
6
7
5
9
4
2
9
6
11
3
4
1
1 2
15
4
15 2
15
2
6
16
Shortest paths in weighted graphs
Definition: The single-source shortest-path problem is the task of finding, for
a graph G = (V,E) and a vertex v V, the shortest paths from v to all other
vertices in G.
Difference from unweighted graphs: The length of a path in a weighted graph
is given by the sum of all weights of the edges contained in the path.
1
3
8
6
7
5
9
4
2
9
6
11
3
4
1
1 2
15
4
15 2
15
2
6
17
Dijkstra’s algorithm
Optimality principle:
For each shortest path p = (v0, v1, . . . , vk) from v0 to vk, each partial path
p´ = (vi, . . . , vj), 0 ≤ i ≤ j ≤ k, is a shortest path from vi to vj .
Proof:
1. Assume the opposite: then there would be a shorter path p´´ from vi to vj,
hence in p the partial path p´ could be replaced by p´´ and the resulting
path from v0 to vk would be shorter than p.
2. However, this contradicts the basic assumption the p is a shortest path
from v0 to vk.
18
Consequence (1)
1. For all shortest paths sp(s, v) and edges (v, v´):
c(sp(s, v)) + c((v, v´)) ≥ c(sp(s, v´))
2. For at least one shortest path sp(s, v) and one edge (v, v´):
c(sp(s, v)) + c((v, v´)) = c(sp(s, v´))
We can compute shortest paths by adding one edge at a time to a shortest path already known, with the following invariant:
19
Consequence (2)
• Let p = (v0, v1, . . . , vk) be a path from v0 to vk.
• Let p´´ be a shorter path from vi to vj than the respective partial path in p.
• Then we can replace the partial path from vi to vj in p by p´´ and obtain a
shorter path p´ from v0 to vk.
20
Idea of Dijkstra’s algorithm
• Initially the distance d(v) of all vertices (other than s) to s is set to .
• Of course, the distance of s to itself is 0.
• We consider a set PQ of vertex-distance pairs (v, d(v)), initially containing
only the element (s, 0).
• Then PQ is modified step by step, according to the “greedy” principle
“vertex with shortest distance to s first”, until PQ is empty:
1. Delete vertex v with minimum distance d(v) to s from PQ.
d(v) is the shortest distance of s to v.
2. For each vertex w V with (v, w) E do:
(a) If w has already been deleted from PQ (see 1), do nothing.
(b) If (w, d(w)) PQ, replace (w, d(w)) by (w, min{d(w); d(v) + c(v,w)}).
(c) If w is not inside in PQ, insert (w, (d(v) + c(v,w)) into PQ.
21
Calculation of the shortest paths
• The above algorithm only gives us the length of the shortest path for each
vertex v´, not the actual path (the sequence of vertices).
• However, if we also store the predecessor of each node, it is easy to calculate
for any vertex v´ the shortest path to the source vertex v.
• We simply proceed from v´ to its predecessor v´´.
• Then we determine (by the same method) the shortest path from v´´ to v.
• If we arrive at v, we stop.
• By this backward way, we obtain the shortest path from v to v´.
22
Required data structures
• For each vertex v, we store the current provisional distance d(v) to the
source vertex s.
• In addition, we store the predecessor of v on the current provisional
shortest path (so we can re-trace the path).
• Furthermore, we need a data structure for the set PQ in order to store
the vertices that still have to be handled. We need to be able to
(a) delete the vertex with minimum distance
(b) decrease the distance d(v) of a given node v
(c) insert a new vertex v with a given distance d(v)
• These are exactly the priority queue operations (with d(v) as priority);
those are efficiently supported by Fibonacci heaps!
23
Pseudo-code
void Dijkstra { FibonacciHeap PQ = new FibonacciHeap(); PQ.insert(s, 0, s);
while ( !PQ.isEmpty ) { x = PQ.deletemin(); x.done = true; for ( (x,y) x.EdgeList ) { if (y.done) return; if (y PQ) if (d(y) > d(x) + c(x,y)) PQ.decreasekey(y, d(x) + c(x,y), x); else PQ.insert(y, d(x) + c(x,y), x); } }
}
24
Example
Source vertex: 1.
1
3
8
6
7
5
9
4
2
9
6
11
3
4
1
1 2
15
4
15 2
15
2
6
25
Example
Entry in PQ: (vertex, distance, predecessor):
(1,0,1)
(2,2,1) , (6,9,1), (7,15,1)
(6,9,1), (7,8,2), (3,6,2)
(6,9,1), (7,8,2) , (4,8,3), (9,21,3)
(6,9,1), (4,8,3) , (9,10,7),
(8,23,7)
(6,9,1) , (8,23,7), (9,9,4), (5,9,4)
(9,9,4) , (5,9,4), (8,20,6)
(5,9,4) , (8,13,9)
(8,12,5)
Ф;
1
3
8
6
7
5
9
4
2
9
6
11
3
4
1
1 2
15
4
15 2
15
2
6
26
Analysis
void Dijkstra { FibonacciHeap PQ = new FibonacciHeap(); PQ.insert(s, 0, s);
while ( !PQ.isEmpty ) { x = PQ.deletemin(); x.done = true; for ( (x,y) x.EdgeList ) { if (y.done) return; if (y PQ) if (d(y) > d(x) + c(x,y)) PQ.decreasekey(y, d(x) + c(x,y), x); else PQ.insert(y, d(x) + c(x,y), x); } }
}
27
Analysis
• The (outer) while-loop has at most |V| iterations, since each node can only
be deleted once!
• Each deletemin takes O(log |V|) amortized time.
• For each vertex, the number of iterations in the (inner) for-loop equals the
number of edges originating from that vertex. Hence, for all the for-loops
together we have a total of |E| iterations.
• Inside the for-loop, each iteration takes O(1) amortized time.
• Hence, the total (amortized) running time is O(|E| + |V | · log |V |).
• NOTE: The running time depends on the representation of the graph
(adjacency matrix/list, double-connected edge list) as well as on the
implementation of the priority queue (linear list, heap, Fibonacci heap).