CSE 373: More on Dijkstras algorithm Michael Lee Wednesday, Feb 21, - - PowerPoint PPT Presentation

cse 373 more on dijkstra s algorithm
SMART_READER_LITE
LIVE PREVIEW

CSE 373: More on Dijkstras algorithm Michael Lee Wednesday, Feb 21, - - PowerPoint PPT Presentation

CSE 373: More on Dijkstras algorithm Michael Lee Wednesday, Feb 21, 2018 1 Dijkstras algorithm Initialization: 2. Set our starting nodes cost to 0 Core loop: 1. Get the next (unvisited) node that has the smallest cost 2. Update all


slide-1
SLIDE 1

CSE 373: More on Dijkstra’s algorithm

Michael Lee Wednesday, Feb 21, 2018

1

slide-2
SLIDE 2

Dijkstra’s algorithm

Initialization:

  • 1. Assign each node an initial cost of ∞
  • 2. Set our starting node’s cost to 0

Core loop:

  • 1. Get the next (unvisited) node that has the smallest cost
  • 2. Update all adjacent vertices (if applicable)
  • 3. Mark current node as “visited”

Idea: Greedily pick node with smallest cost, then update everything possible. Repeat.

2

slide-3
SLIDE 3

Dijkstra’s algorithm

Initialization:

  • 1. Assign each node an initial cost of ∞
  • 2. Set our starting node’s cost to 0

Core loop:

  • 1. Get the next (unvisited) node that has the smallest cost
  • 2. Update all adjacent vertices (if applicable)
  • 3. Mark current node as “visited”

Idea: Greedily pick node with smallest cost, then update everything possible. Repeat.

2

slide-4
SLIDE 4

Dijkstra’s algorithm

Initialization:

  • 1. Assign each node an initial cost of ∞
  • 2. Set our starting node’s cost to 0

Core loop:

  • 1. Get the next (unvisited) node that has the smallest cost
  • 2. Update all adjacent vertices (if applicable)
  • 3. Mark current node as “visited”

Idea: Greedily pick node with smallest cost, then update everything possible. Repeat.

2

slide-5
SLIDE 5

Dijkstra’s algorithm

Metaphor: Treat edges as canals and edge weights as distance. Imagine opening a dam at the starting node. How long does it take for the water to reach each vertex? Caveat: Dijkstra’s algorithm only guaranteed to work for graphs with no negative edge weights. Pronunciation: DYKE-struh (“dijk” rhymes with “bike”)

3

slide-6
SLIDE 6

Dijkstra’s algorithm

Metaphor: Treat edges as canals and edge weights as distance. Imagine opening a dam at the starting node. How long does it take for the water to reach each vertex? Caveat: Dijkstra’s algorithm only guaranteed to work for graphs with no negative edge weights. Pronunciation: DYKE-struh (“dijk” rhymes with “bike”)

3

slide-7
SLIDE 7

Dijkstra’s algorithm

Metaphor: Treat edges as canals and edge weights as distance. Imagine opening a dam at the starting node. How long does it take for the water to reach each vertex? Caveat: Dijkstra’s algorithm only guaranteed to work for graphs with no negative edge weights. Pronunciation: DYKE-struh (“dijk” rhymes with “bike”)

3

slide-8
SLIDE 8

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b f h d c e g 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-9
SLIDE 9

Dijkstra’s algorithm

Suppose we start at vertex “a”: a ∞ b ∞ f ∞ h ∞ d ∞ c ∞ e ∞ g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 We initially assign all nodes a cost of infjnity. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-10
SLIDE 10

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b ∞ f ∞ h ∞ d ∞ c ∞ e ∞ g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 Next, assign the starting node a cost of 0. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-11
SLIDE 11

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f ∞ h ∞ d 4 c 1 e ∞ g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 Next, update all adjacent node costs as well as the backpointers. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-12
SLIDE 12

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f ∞ h ∞ d 4 c 1 e ∞ g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 The pending node with the smallest cost is c, so we visit that next. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-13
SLIDE 13

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f ∞ h ∞ d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 We consider all adjacent nodes. a is fjxed, so we only need to update e. Note the new cost of e is the sum of the weights for a − c and c − e. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-14
SLIDE 14

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f ∞ h ∞ d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 b is the next pending node with smallest cost. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-15
SLIDE 15

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h ∞ d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 The adjacent nodes are c, e, and f . The only node where we can update the cost is f . Note the route a − b − e has the same cost as a − c − e, so there’s no point in updating the backpointer to e. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-16
SLIDE 16

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h ∞ d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 Both d and f have the same cost, so let’s (arbitrarily) pick d next. Note that we can’t adjust any of our neighbors. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-17
SLIDE 17

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h ∞ d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 Next up is f . And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-18
SLIDE 18

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 The only neighbor we is h. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-19
SLIDE 19

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 12 g ∞ 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 h has the smallest cost now. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-20
SLIDE 20

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 12 g 8 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 We update g. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-21
SLIDE 21

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 12 g 8 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 Next up is g. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-22
SLIDE 22

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 11 g 8 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 The two adjacent nodes are f and e. f is fjxed so we leave it

  • alone. We however will update e: our current route is cheaper

then the previous route, so we update both the cost and the backpointer. And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-23
SLIDE 23

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 11 g 8 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 The last pending node is e. We visit it, and check for any unfjxed adjacent nodes (there are none). And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-24
SLIDE 24

Dijkstra’s algorithm

Suppose we start at vertex “a”: a b 2 f 4 h 7 d 4 c 1 e 11 g 8 2 1 4 5 10 2 9 11 2 7 1 3 2 3 1 And we’re done! Now, to fjnd the shortest path, from a to a node, start at the end, trace the red arrows backwards, and reverse the list.

4

slide-25
SLIDE 25

Dijkstra’s algorithm

Core idea in simplifjed pseudocode:

def dijkstra(start): for (v : vertices): set cost(v) to infinity set cost(start) to 0 while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc return backpointers dictionary 5

slide-26
SLIDE 26

Dijkstra’s algorithm

One implementation: inserting extra values into heap

def dijkstra(start): backpointers = empty Dictionary of vertex to vertex costs = Dictionary of vertex to double, initialized to infinity visited = empty Set heap = new Heap<Node with cost>(); heap.put([start, 0]) cost.put(start, 0) while (heap is not empty): current, currentCost = heap.removeMin() skip if visited.contains(current), else visited.add(current) for (edge : current.getOutEdges()): skip if visited.contains(edge.dest), else visited.add(edge.dest) if (newCost < cost.get(edge.dest)): cost.put(edge.dest, newCost) heap.insert([edge.dest, newCost]) backpointers.put(edge.dest, current) return backpointers dictionary 6

slide-27
SLIDE 27

Dijkstra’s algorithm

Another impl: after implementing decreasePriority

def dijkstra(start): backpointers = empty Dictionary of vertex to vertex costs = empty Dictionary of vertex to double heap = new Heap<Node with cost>(); for (v : vertices): heap.put([v, infinity]) costs.put(v, infinity) heap.decreasePriority([start, 0]) costs.put(start, 0) while (heap is not empty): current, currentCost = heap.removeMin() for (edge : current.getOutEdges()): newCost = currentCost + edge.cost if (newCost < cost.get(edge.dest)): cost.put(edge.dest, newCost) heap.decreaseKey([edge.dest, newCost]) backpointers.put(edge.dest, current) return backpointers dictionary 7

slide-28
SLIDE 28

Example

What does Dijkstra’s algorithm do when run on vertex a? a b c d e z 1 1 1 1 90 80 70 60 50

8

slide-29
SLIDE 29

Example

What does Dijkstra’s algorithm do when run on vertex a? a b ∞ c ∞ d ∞ e ∞ z ∞ 1 1 1 1 90 80 70 60 50

8

slide-30
SLIDE 30

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c ∞ d ∞ e ∞ z 90 1 1 1 1 90 80 70 60 50

8

slide-31
SLIDE 31

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c ∞ d ∞ e ∞ z 90 1 1 1 1 90 80 70 60 50

8

slide-32
SLIDE 32

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d ∞ e ∞ z 81 1 1 1 1 90 80 70 60 50

8

slide-33
SLIDE 33

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d ∞ e ∞ z 81 1 1 1 1 90 80 70 60 50

8

slide-34
SLIDE 34

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e ∞ z 72 1 1 1 1 90 80 70 60 50

8

slide-35
SLIDE 35

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e ∞ z 72 1 1 1 1 90 80 70 60 50

8

slide-36
SLIDE 36

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e 4 z 63 1 1 1 1 90 80 70 60 50

8

slide-37
SLIDE 37

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e 4 z 63 1 1 1 1 90 80 70 60 50

8

slide-38
SLIDE 38

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e 4 z 54 1 1 1 1 90 80 70 60 50

8

slide-39
SLIDE 39

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e 4 z 54 1 1 1 1 90 80 70 60 50

8

slide-40
SLIDE 40

Example

What does Dijkstra’s algorithm do when run on vertex a? a b 1 c 2 d 3 e 4 z 54 1 1 1 1 90 80 70 60 50

8

slide-41
SLIDE 41

Misc announcements

◮ Project 1, part 2 regrades will be released later tonight ◮ Project 3, part 1 grades also released later tonight Reminder: if you fjx the errors in your Friday submission, you can get up to half credit back. If you’ve emailed me, and you haven’t heard back, email me again

9

slide-42
SLIDE 42

Misc announcements

◮ Project 1, part 2 regrades will be released later tonight ◮ Project 3, part 1 grades also released later tonight Reminder: if you fjx the errors in your Friday submission, you can get up to half credit back. ◮ If you’ve emailed me, and you haven’t heard back, email me again

9

slide-43
SLIDE 43

Dijkstra’s: why does it work?

Rough intuition: ◮ Suppose a is the next unvisited node with the smallest cost. Suppose b is some unvisited vertex adjacent to a. The quickest path from the start to b is going to be through

  • a. Any other route would be a longer detour (assuming edges

are positive!). So, picking the shortest node will always accurately update the adjacent nodes. (Full proof beyond scope of class)

10

slide-44
SLIDE 44

Dijkstra’s: why does it work?

Rough intuition: ◮ Suppose a is the next unvisited node with the smallest cost. Suppose b is some unvisited vertex adjacent to a. ◮ The quickest path from the start to b is going to be through

  • a. Any other route would be a longer detour (assuming edges

are positive!). So, picking the shortest node will always accurately update the adjacent nodes. (Full proof beyond scope of class)

10

slide-45
SLIDE 45

Dijkstra’s: why does it work?

Rough intuition: ◮ Suppose a is the next unvisited node with the smallest cost. Suppose b is some unvisited vertex adjacent to a. ◮ The quickest path from the start to b is going to be through

  • a. Any other route would be a longer detour (assuming edges

are positive!). ◮ So, picking the shortest node will always accurately update the adjacent nodes. (Full proof beyond scope of class)

10

slide-46
SLIDE 46

Dijkstra’s: why does it work?

Rough intuition: ◮ Suppose a is the next unvisited node with the smallest cost. Suppose b is some unvisited vertex adjacent to a. ◮ The quickest path from the start to b is going to be through

  • a. Any other route would be a longer detour (assuming edges

are positive!). ◮ So, picking the shortest node will always accurately update the adjacent nodes. (Full proof beyond scope of class)

10

slide-47
SLIDE 47

Dijkstra’s: negative edges

What if we have negative edges? Question: What’s the shortest path from s to t according to Dijkstra’s? In reality? 1 10

  • 20

s t z

11

slide-48
SLIDE 48

Dijkstra’s: negative edges

What’s the shortest path now? 5

  • 1
  • 1
  • 1

5

s a b c t

12

slide-49
SLIDE 49

Dijkstra’s: negative edges

Punchline: ◮ If there are negative edges, Dijkstra’s doesn’t work (There exist other algorithms that can handle negative edges – e.g. see Bellman-Ford.) If there are negative cycles, nothing works (Where do negative edges show up? Examples: modeling credit and debit, modeling fmow of energy, etc.)

13

slide-50
SLIDE 50

Dijkstra’s: negative edges

Punchline: ◮ If there are negative edges, Dijkstra’s doesn’t work (There exist other algorithms that can handle negative edges – e.g. see Bellman-Ford.) ◮ If there are negative cycles, nothing works (Where do negative edges show up? Examples: modeling credit and debit, modeling fmow of energy, etc.)

13

slide-51
SLIDE 51

Dijkstra’s: negative edges

Punchline: ◮ If there are negative edges, Dijkstra’s doesn’t work (There exist other algorithms that can handle negative edges – e.g. see Bellman-Ford.) ◮ If there are negative cycles, nothing works (Where do negative edges show up? Examples: modeling credit and debit, modeling fmow of energy, etc.)

13

slide-52
SLIDE 52

Dijkstra’s algorithm: analyzing runtime

Question: what is the worst-case runtime of Dijkstra’s algorithm? Strategy 1: Analyze the code, like we’ve been doing all quarter Strategy 2: Analyze the algorithm more holistically, like we did for DFS and BFS

14

slide-53
SLIDE 53

Dijkstra’s algorithm: analyzing runtime

Question: what is the worst-case runtime of Dijkstra’s algorithm? Strategy 1: Analyze the code, like we’ve been doing all quarter Strategy 2: Analyze the algorithm more holistically, like we did for DFS and BFS

14

slide-54
SLIDE 54

Dijkstra’s algorithm: analyzing runtime via code

Consider this (simplifjed) pseudocode. How do we analyze?

def dijkstra(start): for (v : vertices): set cost(v) to infinity set cost(start) to 0 while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc return backpointers dictionary

(Note: let ts be the time needed to get the next smallest node, and let tu be the time needed to update vertex costs. We’ll treat these as unknowns for now.)

15

slide-55
SLIDE 55

Dijkstra’s algorithm: analyzing runtime via code

Consider this (simplifjed) pseudocode. How do we analyze?

def dijkstra(start): for (v : vertices): set cost(v) to infinity set cost(start) to 0 while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc return backpointers dictionary

(Note: let ts be the time needed to get the next smallest node, and let tu be the time needed to update vertex costs. We’ll treat these as unknowns for now.)

15

slide-56
SLIDE 56

Dijkstra’s algorithm: analyzing runtime via code

Things we know: ◮ Initialization takes O (|V |) time ◮ The while loop repeats |V | times ◮ The inner foreach loop repeats |E| times (???)? ◮ The inner foreach loop does O (tu) work per eiteration ◮ So while loop does O (ts + |E|·tu) work per iteration Final runtime: V V ts E tu Distribute: V V ts V E tu The lone V is dominated by V ts: V ts V E tu

16

slide-57
SLIDE 57

Dijkstra’s algorithm: analyzing runtime via code

Things we know: ◮ Initialization takes O (|V |) time ◮ The while loop repeats |V | times ◮ The inner foreach loop repeats |E| times (???)? ◮ The inner foreach loop does O (tu) work per eiteration ◮ So while loop does O (ts + |E|·tu) work per iteration Final runtime: O (|V | + |V |·(ts + |E|·tu)) Distribute: V V ts V E tu The lone V is dominated by V ts: V ts V E tu

16

slide-58
SLIDE 58

Dijkstra’s algorithm: analyzing runtime via code

Things we know: ◮ Initialization takes O (|V |) time ◮ The while loop repeats |V | times ◮ The inner foreach loop repeats |E| times (???)? ◮ The inner foreach loop does O (tu) work per eiteration ◮ So while loop does O (ts + |E|·tu) work per iteration Final runtime: O (|V | + |V |·(ts + |E|·tu)) Distribute: O (|V | + |V |·ts + |V |·|E|·tu) The lone V is dominated by V ts: V ts V E tu

16

slide-59
SLIDE 59

Dijkstra’s algorithm: analyzing runtime via code

Things we know: ◮ Initialization takes O (|V |) time ◮ The while loop repeats |V | times ◮ The inner foreach loop repeats |E| times (???)? ◮ The inner foreach loop does O (tu) work per eiteration ◮ So while loop does O (ts + |E|·tu) work per iteration Final runtime: O (|V | + |V |·(ts + |E|·tu)) Distribute: O (|V | + |V |·ts + |V |·|E|·tu) The lone |V | is dominated by |V |·ts: O (|V |·ts + |V |·|E|·tu)

16

slide-60
SLIDE 60

Dijkstra’s algorithm: analyzing runtime

Our runtime: O (|V |·ts + |V |·|E|·tu) Question: Do we really need to update vertex costs V E times?

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc 17

slide-61
SLIDE 61

Dijkstra’s algorithm: analyzing runtime

Our runtime: O (|V |·ts + |V |·|E|·tu) Question: Do we really need to update vertex costs |V |·|E| times?

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc 17

slide-62
SLIDE 62

Dijkstra’s algorithm: analyzing runtime

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc

Observations about the foreach loop: We don’t know how many times it runs per each iteration ...but we do know num times it runs across all iterations! Original bound: V ts V E tu We update at most once per edge – so, a tighter bound: V ts E tu

18

slide-63
SLIDE 63

Dijkstra’s algorithm: analyzing runtime

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc

Observations about the foreach loop: ◮ We don’t know how many times it runs per each iteration ...but we do know num times it runs across all iterations! Original bound: V ts V E tu We update at most once per edge – so, a tighter bound: V ts E tu

18

slide-64
SLIDE 64

Dijkstra’s algorithm: analyzing runtime

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc

Observations about the foreach loop: ◮ We don’t know how many times it runs per each iteration ◮ ...but we do know num times it runs across all iterations! Original bound: V ts V E tu We update at most once per edge – so, a tighter bound: V ts E tu

18

slide-65
SLIDE 65

Dijkstra’s algorithm: analyzing runtime

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc

Observations about the foreach loop: ◮ We don’t know how many times it runs per each iteration ◮ ...but we do know num times it runs across all iterations! Original bound: O (|V |·ts + |V |·|E|·tu) We update at most once per edge – so, a tighter bound: V ts E tu

18

slide-66
SLIDE 66

Dijkstra’s algorithm: analyzing runtime

while (we still have unvisited nodes): current = get next smallest node for (edge : current.getOutEdges()): newCost = min(cost(current) + edge.cost, cost(edge.dest)) update cost(edge.dest) to newCost, update backpointers, etc

Observations about the foreach loop: ◮ We don’t know how many times it runs per each iteration ◮ ...but we do know num times it runs across all iterations! Original bound: O (|V |·ts + |V |·|E|·tu) We update at most once per edge – so, a tighter bound: O (|V |·ts + |E|·tu)

18

slide-67
SLIDE 67

Dijkstra’s algorithm: fjnding and updating nodes

Our runtime so far: O (|V |·ts + |E|·tu) Question: So, what exactly is ts and tu? Answer: Depends on how we store nodes and costs!

19

slide-68
SLIDE 68

Dijkstra’s algorithm: fjnding and updating nodes

Our runtime so far: O (|V |·ts + |E|·tu) Question: So, what exactly is ts and tu? Answer: Depends on how we store nodes and costs!

19

slide-69
SLIDE 69

Dijkstra’s algorithm: fjnding and updating nodes

Our runtime so far: O (|V |·ts + |E|·tu) Question: So, what exactly is ts and tu? Answer: Depends on how we store nodes and costs!

19

slide-70
SLIDE 70

Dijkstra’s algorithm: fjnding and updating nodes

Observation: there are two operations we care about: fjnding the node with the min cost, and given a node, updating its cost Ideas: Use a binary heaps: lets us fjnd a node with min cost easily Use a dictionary: lets us update the value corresponding to a node easily

20

slide-71
SLIDE 71

Dijkstra’s algorithm: fjnding and updating nodes

Observation: there are two operations we care about: fjnding the node with the min cost, and given a node, updating its cost Ideas: Use a binary heaps: lets us fjnd a node with min cost easily Use a dictionary: lets us update the value corresponding to a node easily

20

slide-72
SLIDE 72

Dijkstra’s algorithm: fjnding and updating nodes

Observation: there are two operations we care about: fjnding the node with the min cost, and given a node, updating its cost Ideas: ◮ Use a binary heaps: lets us fjnd a node with min cost easily Use a dictionary: lets us update the value corresponding to a node easily

20

slide-73
SLIDE 73

Dijkstra’s algorithm: fjnding and updating nodes

Observation: there are two operations we care about: fjnding the node with the min cost, and given a node, updating its cost Ideas: ◮ Use a binary heaps: lets us fjnd a node with min cost easily ◮ Use a dictionary: lets us update the value corresponding to a node easily

20

slide-74
SLIDE 74

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map V Sorted array V AVL tree log V log V Binary heap log V V The AVL version looks actually pretty reasonable

21

slide-75
SLIDE 75

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map O (|V |) O (|1|) Sorted array V AVL tree log V log V Binary heap log V V The AVL version looks actually pretty reasonable

21

slide-76
SLIDE 76

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree log V log V Binary heap log V V The AVL version looks actually pretty reasonable

21

slide-77
SLIDE 77

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap log V V The AVL version looks actually pretty reasonable

21

slide-78
SLIDE 78

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) The AVL version looks actually pretty reasonable

21

slide-79
SLIDE 79

Dijkstra’s algorithm: fjnding and updating nodes

Exercise: fjll out this table Data structure Remove min (ts) Update cost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) The AVL version looks actually pretty reasonable

21

slide-80
SLIDE 80

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. Assumptions: each vertex is unique; we only decrease the cost Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still log n . Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still log n .

22

slide-81
SLIDE 81

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): ◮ Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. Assumptions: each vertex is unique; we only decrease the cost Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still log n . Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still log n .

22

slide-82
SLIDE 82

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): ◮ Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. ◮ Assumptions: each vertex is unique; we only decrease the cost Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still log n . Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still log n .

22

slide-83
SLIDE 83

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): ◮ Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. ◮ Assumptions: each vertex is unique; we only decrease the cost ◮ Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still log n . ◮ Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still log n .

22

slide-84
SLIDE 84

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): ◮ Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. ◮ Assumptions: each vertex is unique; we only decrease the cost ◮ Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still O (log(n)). ◮ Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still log n .

22

slide-85
SLIDE 85

Dijkstra’s algorithm: fjnding and updating nodes

Another common approach: modify binary heaps so they can update the cost in O (log(n)) time (a “hybrid” binary heap): ◮ Two fjelds: the same heap internal array, and a hash table mapping vertices to their index in the array. ◮ Assumptions: each vertex is unique; we only decrease the cost ◮ Implementing removeMin: Run the standard removeMin heap algorithm. As we swap nodes, add some extra code to keep the hash map up-to-date. This is still O (log(n)). ◮ Implementing updateCost: Use the hash map to get the index of the given node. Run percolateUp, updating the hash map as we go. This is still O (log(n)).

22

slide-86
SLIDE 86

Dijkstra’s algorithm: fjnding and updating nodes

Data structure removeMin (ts) updateCost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) “Hybrid” binary heap log V log V Fibonacci heaps log V Note: Fibonacci heaps are beyond the scope of this class

23

slide-87
SLIDE 87

Dijkstra’s algorithm: fjnding and updating nodes

Data structure removeMin (ts) updateCost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) “Hybrid” binary heap O (log(|V |)) O (log(|V |)) Fibonacci heaps log V Note: Fibonacci heaps are beyond the scope of this class

23

slide-88
SLIDE 88

Dijkstra’s algorithm: fjnding and updating nodes

Data structure removeMin (ts) updateCost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) “Hybrid” binary heap O (log(|V |)) O (log(|V |)) Fibonacci heaps log V Note: Fibonacci heaps are beyond the scope of this class

23

slide-89
SLIDE 89

Dijkstra’s algorithm: fjnding and updating nodes

Data structure removeMin (ts) updateCost (tu) Hash map O (|V |) O (|1|) Sorted array O (1) O (|V |) AVL tree O (log(|V |)) O (log(|V |)) Binary heap O (log(|V |)) O (|V |) “Hybrid” binary heap O (log(|V |)) O (log(|V |)) Fibonacci heaps O (log(|V |)) O (1) Note: Fibonacci heaps are beyond the scope of this class

23

slide-90
SLIDE 90

Dijkstra’s algorithm: fjnding and updating nodes

Observation: Gosh, this all sounds exhausting What if we replace the binary heap’s call to updateCost with insert and just allow duplicates? Runtime is now V E log V E – the analysis is left as an exercise to the reader. So, less effjcient, but easiest to implement.

24

slide-91
SLIDE 91

Dijkstra’s algorithm: fjnding and updating nodes

Observation: Gosh, this all sounds exhausting What if we replace the binary heap’s call to updateCost with insert and just allow duplicates? Runtime is now O ((|V | + |E|) log(|V | + |E|)) – the analysis is left as an exercise to the reader. So, less effjcient, but easiest to implement.

24