Recursive DFS (with visited marker kept on vertex objects) v 2 v 1 void dfs( Vertex v ) { v.visited = true; for each Vertex w adjacent to v v 5 if( !w.visited ) v 3 v 4 dfs( w ); } v 6 v 7 DFS Spanning Tree v 1 v 4 v 3 30
Recursive DFS (with visited marker kept on vertex objects) v 2 v 1 void dfs( Vertex v ) { v.visited = true; for each Vertex w adjacent to v v 5 if( !w.visited ) v 3 v 4 dfs( w ); } v 7 v 6 DFS Spanning Tree v 1 v 4 v 3 v 6 31
Recursive DFS (with visited marker kept on vertex objects) v 2 v 1 void dfs( Vertex v ) { v.visited = true; for each Vertex w adjacent to v v 5 if( !w.visited ) v 3 v 4 dfs( w ); } v 6 v 7 DFS Spanning Tree v 1 v 4 v 3 v 7 v 6 32
Recursive DFS (with visited marker kept on vertex objects) v 2 v 1 void dfs( Vertex v ) { v.visited = true; for each Vertex w adjacent to v if( !w.visited ) v 3 v 4 v 5 dfs( w ); } v 6 v 7 DFS Spanning Tree v 1 v 4 v 3 v 7 v 5 v 6 33
Recursive DFS (with visited marker kept on vertex objects) v 1 v 2 void dfs( Vertex v ) { v.visited = true; for each Vertex w adjacent to v if( !w.visited ) v 3 v 4 v 5 dfs( w ); } v 6 v 7 DFS Spanning Tree v 1 v 4 v 2 v 3 v 7 v 5 v 6 34
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 2 v 1 v 3 v 4 v 5 v 6 v 7 35
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 1 v 2 v 3 v 4 v 5 v 6 v 7 36
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 1 v 2 v 3 v 5 v 4 v 6 v 7 37
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 1: v 2, v 4 v 2: v 4, v 5 v 1 v 2 v 3: v 1, v 6 v 4: v 5 v 5: v 3 v 4 v 5 v 6: v 7 v 6 v 7 v 7: v 5 38
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 1: v 2, v 4 v 2: v 4, v 5 v 1 v 2 v 3: v 1, v 6 v 4: v 5 v 5: v 3 v 4 v 5 v 6: v 7 v 6 v 7 v 7: v 5 • If stack is empty or we reach top of recursion, scan through adjacency list until we find an unseen starting node. 39
DFS on the Entire Graph • It is possible that not all vertices are reachable from a designated start vertex. v 1: v 2, v 4 v 2: v 4, v 5 v 1 v 2 v 3: v 1, v 6 v 4: v 5 v 5: v 3 v 4 v 5 v 6: v 7 v 6 v 7 v 7: v 5 Running time for complete DFS traversal: O(|V|+|E|) • If stack is empty or we reach top of recursion, scan through adjacency list until we find an unseen starting node. 39
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 1 Queue Visited: {v 1 } 40
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 2 v 4 Queue Visited: {v 1, v 2, v 4 } 41
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 4 v 5 Queue Visited: {v 1, v 2, v 4, v 5 } 42
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 5 v 7 v 6 v 3 Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 43
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 7 v 6 v 3 Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 44
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 6 v 3 Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 45
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • v 3 Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 46
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 47
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • adjacent to u : v 6 v 7 if v is not in visited: • Add v to visited. • enqueue(v). • Running time (to traverse the entire graph): O(|V|+|E|) Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 47
Breadth-First Search (BFS) Use a queue and a set visited . v 1 v 2 Enqueue s • Add s to visited • While the queue is not empty: • v 3 v 4 v 5 u <- dequeue() • for each vertex v that is • BFS will traverse the entire adjacent to u : v 6 v 7 graph even without a if v is not in visited: • Add v to visited. • visited set. enqueue(v). • DFS can get stuck in a Running time (to traverse loop. the entire graph): O(|V|+|E|) Queue {v 1, v 2, v 4, v 5, v 7, v 6, v 3 } Visited: 47
Finding Shortest Paths • Goal: Find the shortest path between two vertices s and t. v 1 v 2 v 3 v 4 v 5 v 6 v 7 What is the shortest path between v 3 and v 7 ? 48
Finding Shortest Paths • Goal: Find the shortest path between two vertices s and t. v 1 v 2 v 1 length 3 v 3 v 4 v 5 v 3 v 4 v 6 v 7 v 7 What is the shortest path between v 3 and v 7 ? 49
Finding Shortest Paths • Goal: Find the shortest path between two vertices s and t. • It turns out that finding the shortest path between s and ALL other vertices is just as easy. This problem is called single-source shortest paths . v 1 v 2 v 4 v 5 v 3 v 6 v 7 50
Finding Shortest Paths • Goal: Find the shortest path between two vertices s and t. • It turns out that finding the shortest path between s and ALL other vertices is just as easy. This problem is called single-source shortest paths . 2 v 1 v 2 1 3 2 v 4 v 5 v 3 3 v 6 v 7 1 50
Finding Shortest Paths • Goal: Find the shortest path between two vertices s and t. • It turns out that finding the shortest path between s and ALL other vertices is just as easy. This problem is called single-source shortest paths . 2 v 1 v 2 1 3 2 v 4 v 5 v 3 3 v 6 v 7 1 50
Finding Shortest Paths with BFS ∞ ∞ v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • ∞ ∞ 0 enqueue s • v 3 v 4 v 5 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • ∞ ∞ to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 3 Queue 51
Finding Shortest Paths with BFS 1 ∞ v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • ∞ ∞ 0 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 1 v 6 Queue 52
Finding Shortest Paths with BFS 1 2 v 2 v 1 s.distance = 0 • for all v ∈ V set v.distance = ∞ • ∞ 0 2 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 6 v 2 v 4 Queue 53
Finding Shortest Paths with BFS 1 2 v 2 v 1 s.distance = 0 • for all v ∈ V set v.distance = ∞ • ∞ 0 2 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 7 v 6 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 2 v 4 Queue 54
Finding Shortest Paths with BFS 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 0 2 3 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 7 v 6 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 4 v 5 Queue 55
Finding Shortest Paths with BFS 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 0 2 3 enqueue s • v 5 v 3 v 4 While the queue is not empty: • u <- dequeue() • v 7 v 6 for each vertex v that is adjacent • 1 3 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 5 v 7 Queue 56
Finding Shortest Paths with BFS 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 0 2 3 enqueue s • v 3 v 4 v 5 While the queue is not empty: • u <- dequeue() • v 7 v 6 for each vertex v that is adjacent • 1 3 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(v) • v 7 Queue 57
Finding Shortest Paths with BFS 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 0 2 3 enqueue s • v 3 v 4 v 5 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • 1 3 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(u) • Queue 58
Finding Shortest Paths with BFS 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 0 2 3 enqueue s • v 3 v 4 v 5 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • 1 3 to u: if v.distance == ∞ • v.distance = u.distance + 1 • enqueue(u) • This is just BFS. Running time: O(|V|+|E|) Queue 58
Finding Shortest Paths with BFS - Back pointers Maintain pointers to the previous node on the shortest path. 1 ∞ v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • ∞ ∞ 0 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.prev = u • v.distance = u.distance + 1 • enqueue(v) • v 1 v 6 Queue 59
Finding Shortest Paths with BFS - Back pointers Maintain pointers to the previous node on the shortest path. 1 2 v 1 v 2 s.distance = 0 • for all v ∈ V set v.distance = ∞ • 2 ∞ 0 enqueue s • v 4 v 5 v 3 While the queue is not empty: • u <- dequeue() • v 6 v 7 for each vertex v that is adjacent • ∞ 1 to u: if v.distance == ∞ • v.prev = u • v.distance = u.distance + 1 • enqueue(v) • v 6 v 2 v 4 Queue 60
Weighted Shortest Paths • Goal: Find the shortest path between two vertices s and t. 2 v 1 v 2 10 3 4 1 2 2 v 3 v 4 v 5 8 4 6 5 1 v 6 v 7 What is the shortest path between v 2 and v 6 ? 61
Weighted Shortest Paths • Goal: Find the shortest path between two vertices s and t. • Normal BFS will find this path. 2 v 1 v 2 length 2 10 3 4 1 cost 11 2 2 v 3 v 5 v 4 8 4 6 5 1 v 7 v 6 What is the shortest path between v 2 and v 6 ? 62
Weighted Shortest Paths • Goal: Find the shortest path between two vertices s and t. • This path is shorter. 2 v 1 v 2 length 3 10 3 4 1 cost 8 2 2 v 3 v 5 v 4 8 4 6 5 1 v 6 v 7 What is the shortest path between v 2 and v 6 ? 63
Negative Weights • We normally expect the shortest path to be simple. • Edges with Negative Weights can lead to negative cycles. • The concept of “shortest path” is then not clearly defined. 2 v 1 v 2 10 3 4 -7 2 2 v 5 v 3 v 4 8 4 6 5 1 v 6 v 7 What is the shortest path between v 2 and v 6 ? 64
Dijkstra’s Algorithm for Weighted Shortest Path 65
Dijkstra’s Algorithm for Weighted Shortest Path • Cost annotations for each vertex reflect the lowest cost using only vertices visited so far. 65
Dijkstra’s Algorithm for Weighted Shortest Path • Cost annotations for each vertex reflect the lowest cost using only vertices visited so far. • That means there might be a lower-cost path through other vertices that have not been seen yet. 65
Dijkstra’s Algorithm for Weighted Shortest Path • Cost annotations for each vertex reflect the lowest cost using only vertices visited so far. • That means there might be a lower-cost path through other vertices that have not been seen yet. • Keep nodes on a priority queue and always expand the vertex with the lowest cost annotation first! • Intuitively, this means we will never overestimate the cost and miss lower-cost path. 65
Dijkstra’s Algorithm for Weighted Shortest Path • Cost annotations for each vertex reflect the lowest cost using only vertices visited so far. • That means there might be a lower-cost path through other vertices that have not been seen yet. • Keep nodes on a priority queue and always expand the vertex with the lowest cost annotation ← This is a greedy algorithm first! • Intuitively, this means we will never overestimate the cost and miss lower-cost path. 65
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false ∞ 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 ∞ ∞ 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 ∞ 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • ∞ ∞ if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 66
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 2 v 1 q.insert(s) 10 • 3 4 1 ∞ 1 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 ∞ 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • ∞ ∞ if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 67
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 2 v 1 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 5 v 4 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 9 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 68
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 5 v 4 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 9 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 69
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 9 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 70
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 9 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 71
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 6 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 72
Dijkstra’s Algorithm Use a Priority Queue q for all v ∈ V • set v.cost = ∞ , set v.visited = false 2 0 2 s.cost = 0, s.visited = true; • v 1 v 2 q.insert(s) 10 • 3 4 1 3 1 2 2 While q is not empty: • v 3 v 4 v 5 u <- q .deleteMin() 8 • 4 6 3 5 u.visited = true • 1 v 6 v 7 for each edge ( u,v) : • 5 6 if not v.visited: • if (u.cost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert(v) • 73
Dijkstra’s Algorithm - a subtle bug 2 0 2 v 1 v 2 While q is not empty: • 10 u <- q .deleteMin() 3 4 • 1 3 1 u.visited = true • 2 2 v 3 v 4 v 5 for each edge ( u,v) : • 8 4 if not v.visited: 6 3 • 5 if (u.cost + cost(u,v) < v.cost) 1 • v 6 v 7 v.cost = u.cost + cost(u,v) • 5 9 v.prev = u • q.insert(v) • v 7 .cost +cost(v 6, v 7 ) = 6 74
Dijkstra’s Algorithm - a subtle bug 2 0 2 v 1 v 2 While q is not empty: • 10 u <- q .deleteMin() 3 4 • 1 3 1 u.visited = true • 2 2 v 3 v 4 v 5 for each edge ( u,v) : • 8 4 if not v.visited: 6 3 • 5 if (u.cost + cost(u,v) < v.cost) 1 • v 6 v 7 v.cost = u.cost + cost(u,v) • 5 9 v.prev = u • q.insert(v) • v 7 .cost +cost(v 6, v 7 ) = 6 • v 7 is already in q , and has not been visited. • does insert(v 7 ) create a new entry in the q or update the existing one? • if q is a heap, updating the cost will change v 7 everywhere in the heap and might make the heap invalid. 74
Dijkstra’s Algorithm - Fixed 2 0 2 v 1 v 2 Use a Priority Queue q 10 3 4 1 for all v ∈ V • 3 1 2 2 set v.cost = ∞ , set v.visited = false v 3 v 4 v 5 8 s.cost = 0 4 • 6 3 5 q.insert( (0, s) ) • 1 v 6 v 7 5 9 While q is not empty: • (costu, u) <- q .deleteMin() • if not u.visited: • v 7 .cost +cost(v 6, v 7 ) = 6 u.visited = true • for each edge ( u,v) : • •Keep a separate cost if not v.visited: • object in the queue if ( costu + cost(u,v) < v.cost) • that isn’t updated. v.cost = u.cost + cost(u,v) • •Ignore duplicate v.prev = u • q.insert( (v.cost, v) ) entries for vertices. • 75
Dijkstra’s Running Time • There are |E| insert and Use a Priority Queue q deleteMin operations. for all v ∈ V • set v.cost = ∞ , set v.visited = false • The maximum size of s.cost = 0 • q.insert((0, s)) • the priority queue is O(|E|). Each insert While q is not empty: • takes O(log |E|) (costu, u) <- q .deleteMin() • if not u.visited: • O(|E| log |E|) u.visited = true • for each edge ( u,v) : • if not v.visited: • if (ucost + cost(u,v) < v.cost) • v.cost = u.cost + cost(u,v) • v.prev = u • q.insert((v.cost, v)) • 76
Dijkstra’s Running Time • There are |E| insert and Use a Priority Queue q deleteMin operations. for all v ∈ V • set v.cost = ∞ , set v.visited = false • The maximum size of s.cost = 0 • q.insert((0, s)) • the priority queue is O(|E|). Each insert While q is not empty: • takes O(log |E|) (costu, u) <- q .deleteMin() • if not u.visited: • O(|E| log |E|) u.visited = true • =O(|E| log |V|) for each edge ( u,v) : • because |E| ≤ |V| 2, if not v.visited: • if (ucost + cost(u,v) < v.cost) • and therefore v.cost = u.cost + cost(u,v) • log |E| ≤ 2 log |V| v.prev = u • q.insert((v.cost, v)) • 76
Topological Sort in DAGs A topological sort of a DAG is an ordering of its vertices such that if there is a path from u to w , u appears before w in the ordering. W1004 W3134 W4115 W3261 W4156 W3203 W4111 W1007 W3137 W4701 W3157 77
Topological Sort in DAGs A topological sort of a DAG is an ordering of its vertices such that if there is a path from u to w , u appears before w in the ordering. W1007 W1004 W1004 W3134 W4115 W3261 W4156 W3203 W4111 W1007 W3137 W4701 W3157 78
Topological Sort in DAGs A topological sort of a DAG is an ordering of its vertices such that if there is a path from u to w , u appears before w in the ordering. W3203 W1007 W1004 W3134 W3137 W3157 W1004 W3134 W4115 W3261 W4156 W3203 W4111 W1007 W3137 W4701 W3157 79
Topological Sort in DAGs A topological sort of a DAG is an ordering of its vertices such that if there is a path from u to w , u appears before w in the ordering. W3203 W4111 W1007 W1004 W3134 W3137 W3157 W3261 W4701 W1004 W3134 W4115 W3261 W4156 W3203 W4111 W1007 W3137 W4701 W3157 80
Topological Sort in DAGs A topological sort of a DAG is an ordering of its vertices such that if there is a path from u to w , u appears before w in the ordering. W3203 W4111 W1007 W1004 W3134 W3137 W3157 W3261 W4701 W4115 W4156 W1004 W3134 W4156 W3261 W4115 W3203 W4111 W1007 W3137 W4701 W3157 81
Application: Critical Path Analysis • An Event-Node Graph is a DAG in which • Edges represent tasks, weight represents the time it takes to complete the task. • Vertices represent the event of completing a set of tasks. write edit proofread articles 1 3 1 layout printing distribution 3 3 6 c 2 o m 1 m process p i h s i o o w photographs t n o e g b d r a 1 n a l p a o h 2 o y i s o l s p u r u e t v e n i l n o 82
Application: Critical Path Analysis • We are interested in the earliest completion time. (Earliest time we can reach the final event). • This is equivalent to finding the longest path through the DAG (why does this not work with cycles?). write edit proofread articles 1 3 1 layout printing distribution 3 3 6 c 2 o m 1 m process p i h s i o o w photographs t n o e g b d r a 1 n a l p a o h 2 o y i s o l s p u r u e t v e n i l n o 83
Application: Critical Path Analysis • If an event has more than one incoming event, all tasks have to be finished before other tasks can proceed. write edit proofread articles 1 3 1 layout printing distribution 3 3 6 c 2 o m 1 m process p i h s i o o w photographs t n o e g b d r a 1 n a l p a o h 2 o y i s o l s p u r u e t v e n i l n o 84
Application: Critical Path Analysis • Basic idea: Compute the earliest completion time for each event. • Can use Dijkstra’s algorithm O(|E| log |V|). • We now try to find the longest path. write edit proofread articles 1 3 1 layout printing distribution 0 3 3 6 c 2 o m 1 m process p i h s i o o w photographs t n o e g b d r a 1 n a l p a o h 2 o y i s o l s p u r u e t v e n i l n o 85
Recommend
More recommend