Download presentation

Presentation is loading. Please wait.

Published byMercedes Hamlyn Modified about 1 year ago

1
1 Theory I Algorithm Design and Analysis (10 - Shortest paths in graphs) T. Lauer

2
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
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
4 Example of a digraph 1 3 8 6 7 5 9 4 2

5
5 Adjacency matrix Graphs can be stored as adjacency matrices. A graph G = (V,E) is stored in a Boolean |V | x |V | matrix A G = (a ij ), 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 Eji Eji a ij ),(1 ),(0

6
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 1 2 3 6 7 5 4

7
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
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
9 An example 3 7 2 64658 5 1 1 2 3 4 5 6 7 8 9

10
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
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
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
13 Doubly-connected edge lists: example 1 2 3 4 5 6 7 8 9

14
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 1 2 3 6 7 5 4

15
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 R 0 + 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 2 2 6

16
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 2 2 6

17
17 Dijkstra’s algorithm Optimality principle: For each shortest path p = (v 0, v 1,..., v k ) from v 0 to v k, each partial path p´ = (v i,..., v j ), 0 ≤ i ≤ j ≤ k, is a shortest path from v i to v j. Proof: 1.Assume the opposite: then there would be a shorter path p´´ from v i to v j, hence in p the partial path p´ could be replaced by p´´ and the resulting path from v 0 to v k would be shorter than p. 2.However, this contradicts the basic assumption the p is a shortest path from v 0 to v k.

18
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
19 Consequence (2) Let p = (v 0, v 1,..., v k ) be a path from v 0 to v k. Let p´´ be a shorter path from v i to v j than the respective partial path in p. Then we can replace the partial path from v i to v j in p by p´´ and obtain a shorter path p´ from v 0 to v k.

20
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
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
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
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
24 Example Source vertex: 1. 1 3 8 6 7 5 9 4 2 9 6 11 3 4 1 1 2 15 4 2 2 6

25
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 2 2 6

26
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
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).

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google