1 of 120

Shortest Paths

1

Lecture 24 (Graphs 3)

CS61B, Fall 2023 @ UC Berkeley

Slides credit: Josh Hug

2 of 120

Shortest Paths: Why BFS Doesn't Work

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

3 of 120

Graph Problems

Last time, saw two ways to find paths in a graph.

  • DFS and BFS.

Which is better?

Problem

Problem Description

Solution

Efficiency (adj. list)

s-t paths

Find a path from s to every reachable vertex.

DepthFirstPaths.java

Demo

O(V+E) time

Θ(V) space

s-t shortest paths

Find a shortest path from s to every reachable vertex.

BreadthFirstPaths.java

Demo

O(V+E) time

Θ(V) space

4 of 120

BFS vs. DFS for Path Finding

Possible considerations:

  • Correctness. Do both work for all graphs?
    • Yes!
  • Output Quality. Does one give better results?
    • BFS is a 2-for-1 deal, not only do you get paths, but your paths are also guaranteed to have the fewest edges.
  • Time Efficiency. Is one more efficient than the other?
    • Should be very similar. Both consider all edges twice. Experiments or very careful analysis needed.

5 of 120

BFS vs. DFS for Path Finding

  • Space Efficiency. Is one more efficient than the other?
    • DFS is worse for spindly graphs.
      • Call stack gets very deep.
      • Computer needs Θ(V) memory to remember recursive calls (see CS61C).
    • BFS is worse for absurdly “bushy” graphs.
      • Queue gets very large. In worst case, queue will require Θ(V) memory.
      • Example: 1,000,000 vertices that are all connected. 999,999 will be enqueued at once.
    • Note: In our implementations, we have to spend Θ(V) memory anyway to track distTo and edgeTo arrays.
      • Can optimize by storing distTo and edgeTo in a map instead of an array.

6 of 120

BreadthFirstSearch for Google Maps

As we discussed last time, BFS would not be a good choice for a google maps style navigation application.

  • The problem: BFS returns path with shortest number of edges, not necessarily the shortest path.

Let’s see a quick example.

7 of 120

Breadth First Search for Mapping Applications

Suppose we’re trying to get from s to t.

s

t

8 of 120

Breadth First Search for Mapping Applications

Suppose we’re trying to get from s to t.

s

t

260

70

70

10

70

40

20

15

30

50

9 of 120

Breadth First Search for Mapping Applications

BFS yields the wrong route from s to t.

  • No: BFS yields a route of length ~330 m instead of ~130 m.
  • We need an algorithm that takes into account edge distances, also known as “edge weights”!

BFS Result

Correct Result

s

t

260

70

70

10

70

30

40

20

15

50

s

t

260

70

70

10

70

40

20

15

30

50

10 of 120

Goal: The Shortest Paths Tree

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

11 of 120

Problem: Single Source Single Target Shortest Paths

Goal: Find the shortest paths from source vertex s to some target vertex t.

Challenge: Try to find the shortest path from town 0 to town 5.

  • Each edge has a number representing the length of that road in miles.

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

1

12 of 120

Problem: Single Source Single Target Shortest Paths

Goal: Find the shortest paths from source vertex s to some target vertex t.

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

1

Best path from 0 to 5 is

  • 0 -> 1 -> 4 -> 5.
  • Total length is 9 miles.

The path 0 -> 2 -> 5 only involves three towns, but total length is 16 miles.

13 of 120

Problem: Single Source Single Target Shortest Paths

Goal: Find the shortest paths from source vertex s to some target vertex t.

Observation: Solution will always be a path with no cycles (assuming non-negative weights).

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

1

v distTo[] edgeTo[]

0 0.0 -

1 2.0 0→1

2 - -

3 - -

4 5.0 1→4

5 9.0 4→5

6 - -

Shortest path from s=0 to t=5

14 of 120

Problem: Single Source Shortest Paths

Goal: Find the shortest paths from source vertex s to every other vertex.

Challenge: Try to write out the solution for this graph.

  • You should notice something interesting.

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

1

15 of 120

Problem: Single Source Shortest Paths

Goal: Find the shortest paths from source vertex s to every other vertex.

Observation: Solution will always be a tree.

  • Can think of as the union of the shortest paths to all vertices.

v distTo[] edgeTo[]

0 0.0 -

1 2.0 0→1

2 1.0 0→1

3 11.0 6→3

4 5.0 1→4

5 9.0 4→5

6 10.0 4→6

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

1

Shortest paths from s=0

16 of 120

SPT Edge Count: yellkey.com/TODO

If G is a connected edge-weighted graph with V vertices and E edges, how many edges are in the Shortest Paths Tree (SPT) of G? [assume every vertex is reachable]

B

C

D

E

F

G

A

s

17 of 120

SPT Edge Count

If G is a connected edge-weighted graph with V vertices and E edges, how many edges are in the Shortest Paths Tree (SPT) of G? [assume every vertex is reachable]

V: 7

Number of edges in SPT is 6

Always V-1:

  • For each vertex, there is exactly one input edge (except source).

B

C

D

E

F

G

A

s

18 of 120

Dijkstra's Algorithm: Some Bad Algorithms

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

19 of 120

Finding a Shortest Paths Tree (By Hand)

What is the shortest paths tree for the graph below? Note: Source is A.

B

C

A

s

5

5

D

1

2

2

1

20 of 120

Finding a Shortest Paths Tree (By Hand)

What is the shortest paths tree for the graph below?

  • Annotation in magenta shows the total distance from the source.

4

B

C

A

s

5

5

D

1

1

0

2

2

2

1

21 of 120

Creating an Algorithm

Let’s create an algorithm for finding the shortest paths.

Will start with a bad algorithm and then successively improve it.

  • Algorithm begins in state below. All vertices unmarked. All distances infinite. No edges in the SPT.

B

C

A

s

5

5

D

1

2

2

1

22 of 120

Finding a Shortest Paths Tree Algorithmically (Incorrect)

Bad algorithm #1: Perform a depth first search. When you visit v:

  • For each edge from v to w, if w is not already part of SPT, add the edge.

dfs(A):

Add A->B to SPT

Add A->C to SPT

dfs(B):

Add B->D to SPT

A already in SPT.

dfs(C):

B already in SPT.

D already in SPT.

7

B

C

A

s

5

5

D

1

1

0

5

3

2

1

B

C

A

s

5

1

D

1

0

3

2

5

5

1

B

C

A

s

5

1

5

D

1

1

0

5

3

2

7

Older slide, used on the web videos.

23 of 120

Finding a Shortest Paths Tree Algorithmically (Incorrect)

Bad algorithm #2: Perform a depth first search. When you visit v:

  • For each edge from v to w, add edge to the SPT only if that edge yields better distance.

dfs(A):

A->B is 5, < than

A->C is 1, < than

dfs(B):

B->D is 5 + 2 = 7, better than .

B->A is 5 + 3 = 8, worse than 0.

dfs(C):

C->B is 1 + 1 = 2, better than 5.

C->D is 1 + 5 = 6, better than 7.

B

C

A

s

5

1

D

1

0

3

2

5

We’ll call this process “edge relaxation”.

Improvements:

  • Use better edges if found.

1

5

B

C

A

s

5

1

5

D

1

1

0

5

3

2

7

7

B

C

A

s

5

5

D

1

1

0

5

3

2

1

2

6

Older slide, used on the web videos.

24 of 120

Finding a Shortest Paths Tree Algorithmically (Incorrect)

Dijkstra’s Algorithm: Perform a best first search (closest first). When you visit v:

  • For each from v to w, relax that edge.

A has lowest dist, so dfs(A):

A->B is 5, < than

A->C is 1, < than

C has lowest dist, so dfs(C):

C->B is 1 + 1 = 2, better than 5.

C->D is 1 + 5 = 6, better than .

B has lowest dist, so dfs(B):

B->A is 2 + 3 = 5, worse than 0.

B->D is 2 + 2 = 4, better than 6.

B

C

A

s

5

1

D

1

0

3

2

5

Improvements:

  • Use better edges if found.
  • Traverse “best first”.

1

5

B

C

A

s

5

1

5

D

1

1

0

5

3

2

2

6

6

B

C

A

s

5

5

D

1

1

0

2

3

2

1

4

Older slide, used on the web videos.

25 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

26 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

Fringe: [A]

27 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

Fringe: [A]

Removed vertex: A

28 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

Fringe: [A, B, C]

Removed vertex: A

29 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

Fringe: [A, B, C]

Removed vertex: B

30 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

7

The edge B→A is not added to SPT, because A is already part of the SPT.

Fringe: [A, B, C, D]

Removed vertex: B

31 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

7

Fringe: [A, B, C, D]

Removed vertex: C

32 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

7

Nothing happens.

C→B not added, B already in SPT.

C→D not added, D already in SPT.�

Fringe: [A, B, C, D]

Removed vertex: C

33 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

7

Fringe: [A, B, C, D]

Removed vertex: D

34 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

B

C

A

s

5

5

D

1

2

2

1

5

1

7

Fringe: [A, B, C, D]

Removed vertex: D

Nothing happens.

D has no neighbors (there are no edges going out of D).

35 of 120

Bad Algorithm #1 (Inspired by BFS)

Add the start (A) to the fringe.

While fringe is not empty:

Remove a vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Takeaways:

  • This algorithm would work if all our edges were the same length.

Algorithm #1 (BFS) visits:� every node 1 edge away,�then every node 2 edges away,�then every node 3 edges away, etc.

36 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

2

2

1

B

C

A

s

D

Order of visited nodes:

37 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

0

2

2

1

B

C

A

s

D

0

Order of visited nodes: A

38 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

1

0

2

2

1

B

C

A

s

D

1

0

Order of visited nodes: AC

39 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

1

0

2

2

2

1

B

C

A

s

D

1

0

2

Order of visited nodes: ACB

40 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

1

0

2

2

2

1

B

C

A

s

D

1

0

2

Order of visited nodes: ACB

41 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

1

0

2

2

2

1

B

C

A

s

D

1

0

2

4

4

Order of visited nodes: ACBD

42 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

  • When we hit one of our original nodes, add edge to the SPT.

B

C

A

s

5

5

D

1

1

0

2

2

2

1

B

C

A

s

D

1

0

2

4

4

Order of visited nodes: ACBD

43 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

Takeaways:

  • It works, but can be really slow. For example, consider the graph below.
  • What if we measured in inches instead of miles? Or had fractional weights?

B

C

A

s

316800

D

316800

126720

126720

63360

63360

44 of 120

Bad Algorithm #2 (Dummy Nodes)

Bad algorithm #2: Create a new graph by adding a bunch of dummy nodes every unit along an edge, then run breadth-first search.

Takeaways:

  • Algorithm #2 order is sometimes called best-first order.
  • Let's try to visit the nodes in the same order as Algorithm #2 did, but without creating dummy nodes.

Algorithm #1 (BFS) visits:� every node 1 edge away,�then every node 2 edges away,�then every node 3 edges away, etc.

Algorithm #2 (dummy nodes) visits:� every node distance 1 away,�then every node distance 2 away,�then every node distance 3 away, etc.

45 of 120

Bad Algorithm #3 (Best-First Search)

Bad algorithm #3: Perform best-first search.

  • Similar to BFS, but we remove the closest edge from the fringe each time.
  • We can use a priority queue to track the closest edge.

B

C

A

s

5

5

D

1

2

2

1

46 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Fringe: [A=0]

B

C

A

s

5

5

D

1

0

2

2

1

Only difference from Algorithm #1: We added the word "closest".

47 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Fringe: [A=0]

Removed vertex: A

B

C

A

s

5

5

D

1

0

2

2

1

48 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5]

Removed vertex: A

B

C

A

s

5

5

D

1

0

2

2

1

5

1

49 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5]

Removed vertex: C

B

C

A

s

5

5

D

1

0

2

2

1

5

1

In BFS, we removed B here, but in best-first, we're removing C because it's closer.

50 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: C

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

51 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: B

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

52 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: B

The only outgoing edge is B→D.�D is already part of the SPT, so do nothing.

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

53 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,� add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: D

B

C

A

s

5

5

D

1

0

2

2

1

1

6

54 of 120

Bad Algorithm #3 (Best-First Search)

Add the start (A) to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if w is not already part of SPT,add the edge, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: D

No outgoing edges from D, so do nothing.

B

C

A

s

5

5

D

1

0

2

2

1

1

6

55 of 120

Bad Algorithm #3 (Best-First Search)

Bad algorithm #3: Perform best-first search.

  • Similar to BFS, but we remove the closest edge from the fringe each time.
  • We can use a priority queue to track the closest edge.

Takeaways:

  • Pro: We visited the nodes in best-first order (same order as in Algorithm #2), without creating dummy nodes.
  • Con: We got the wrong answer. Why?
  • Let's revisit the step where things went wrong.

56 of 120

Bad Algorithm #3 (Best-First Search)

For each outgoing edge v→w: if w is not already part of SPT, add the edge,�mark w, and add w to fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: C

We should have added edge C→B, and thrown out the old edge (A→B) to B. Why?

The distance to B via C→B is 2.

This is better than the currently best known distance to B (5, via A→B).

C→B edge: B was in the SPT (via A→B), so we did nothing.

What should we have done here?

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

57 of 120

Finding a Shortest Paths Tree Algorithmically

Dijkstra's Algorithm:

  • So far, we've added an edge v→w if w is not already part of the SPT.
  • Instead, we should add an edge if that edge yields better distance.
  • Use the priority queue to track best known distances.

B

C

A

s

5

5

D

1

2

2

1

We'll call this process “edge relaxation”.

58 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, � add the edge, and update w in the fringe.

Fringe: [A=0, B=∞, C=∞, D=∞]

B

C

A

s

5

5

D

1

0

2

2

1

Key difference from Algorithm #3: The condition for adding an edge.

(This used to say "if w not in SPT").

Extra bookkeeping: Instead of adding to the fringe as we go, we'll add all vertices to start.

This lets us track the best known distance to each vertex.

59 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, � add the edge, and update w in the fringe.

Fringe: [A=0, B=∞, C=∞, D=∞]

Removed vertex: A

B

C

A

s

5

5

D

1

0

2

2

1

60 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=∞]

Removed vertex: A

B

C

A

s

5

5

D

1

0

2

2

1

5

1

61 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, � add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=∞]

Removed vertex: C

B

C

A

s

5

5

D

1

0

2

2

1

5

1

62 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: C

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

2

Improvement: We used C→B because the distance via C→B (2) is better than the distance via A→B (5).

This also means we throw out the old edge (A→B) to B.

63 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, � add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: B

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

2

64 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: B

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

2

B→A (total=4) is not better than the best known way to A (0).

B→D (total=4) is better than the best known way to D (6, via C→D).�So, we'll update the path to D.

4

65 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, � add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: D

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

2

4

66 of 120

Finding a Shortest Paths Tree Algorithmically

Add all vertices to the fringe.

While fringe is not empty:

Remove the closest vertex from the fringe and mark it.

For each outgoing edge v→w: if the edge gives a better distance to w, add the edge, and update w in the fringe.

Fringe: [A=0, C=1, B=5, D=6]

Removed vertex: D

No outgoing edges from D, so do nothing.

B

C

A

s

5

5

D

1

0

2

2

1

5

1

6

2

4

67 of 120

Dijkstra's Algorithm

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

68 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

5

2

1

15

3

2

11

5

1

1

4

0

1

69 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B ∞ -

C ∞ -

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(B: ∞), (C: ∞), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

70 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(C: 1), (B: 2), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

2

1

71 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(B: 2), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

2

1

72 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F 16 C

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(B: 2), (F: 16), (D: ∞), (E: ∞), (G: ∞)]

4

0

1

2

16

1

73 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F 16 C

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(F: 16), (D: ∞), (E: ∞), (G: ∞)]

4

0

1

2

16

1

74 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 16 C

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(E: 5), (D: 13), (F: 16), (G: ∞)]

4

0

1

2

16

5

13

1

Vertex C unchanged since 2+5 > 1

Which vertex is removed next?

75 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 16 C

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(D: 13), (F: 16), (G: ∞)]

4

0

1

2

16

5

13

1

76 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

  • Show distTo, edgeTo, and fringe after relaxation.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 16 C

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(D: 13), (F: 16), (G: ∞)]

4

0

1

2

16

5

13

1

77 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: [(F: 9), (G: 10), (D: 13)]

4

0

1

2

16

5

13

1

9

10

Vertex 2 unchanged since 5+1 > 1

78 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: [(G: 10), (D: 13)]

4

0

1

2

5

13

1

9

10

79 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 11 G

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: [(D: 11)]

4

0

1

2

5

13

1

9

10

11

80 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 11 G

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: []

4

0

1

2

5

11

1

9

10

Vertex E unchanged since 11 + 2 > 5

Note: If non-negative weights, impossible for any inactive vertex (white, not on fringe) to be improved!

81 of 120

Dijkstra’s Demo

Insert all vertices into fringe PQ, storing vertices in order of distance from source.

Repeat: Remove (closest) vertex v from PQ, and relax all edges pointing from v.

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 11 G

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: []

4

1

82 of 120

Why Dijkstra's is Correct

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

83 of 120

Dijkstra’s Algorithm Pseudocode

Key invariants:

  • edgeTo[v] is the best known predecessor of v.
  • distTo[v] is the best known total distance from source to v.
  • PQ contains all unvisited vertices in order of distTo.

Important properties:

  • Always visits vertices in order of total distance from source.
  • Relaxation always fails on edges to visited (white) vertices.�

Dijkstra’s:

  • PQ.add(source, 0)
  • For other vertices v, PQ.add(v, infinity)
  • While PQ is not empty:
    • p = PQ.removeSmallest()
    • Relax all edges from p

Relaxing an edge p → q with weight w:

  • If distTo[p] + w < distTo[q]:
    • distTo[q] = distTo[p] + w
    • edgeTo[q] = p
    • PQ.changePriority(q, distTo[q])

84 of 120

Guaranteed Optimality

Dijkstra’s Algorithm:

  • Visit vertices in order of best-known distance from source. On visit, relax every edge from the visited vertex.

Dijkstra’s is guaranteed to return a correct result if all edges are non-negative.

85 of 120

Guaranteed Optimality

Dijkstra’s is guaranteed to be optimal so long as there are no negative edges.

  • Proof relies on the property that relaxation always fails on edges to visited (white) vertices.

Proof sketch: Assume all edges have non-negative weights.

  • At start, distTo[source] = 0, which is optimal.
  • After relaxing all edges from source, let vertex v1 be the vertex with minimum weight, i.e. that is closest to the source. Claim: distTo[v1] is optimal, and thus future relaxations will fail. Why?
    • distTo[p] ≥ distTo[v1] for all p, therefore
    • distTo[p] + w ≥ distTo[v1]
  • Can use induction to prove that this holds for all vertices after dequeuing.

86 of 120

Guaranteed Optimality

At start, distTo[source] = 0, which is optimal.

S

s

0

v2

v1

>c

c

v3

>c

>c

v4

87 of 120

Guaranteed Optimality

After relaxing all edges from source, let vertex v1 be the vertex with minimum weight, i.e. that is closest to the source.

S

s

0

v2

v1

>c

c

>c

c

v3

>c

>c

>c

v4

>c

88 of 120

Guaranteed Optimality

Claim: distTo[v1] is optimal, and thus future relaxations will fail. Why?

  • distTo[p] distTo[v1] for all p, therefore
  • distTo[p] + wdistTo[v1]

S

s

0

v2

v1

>c

c

>c

c

v3

>c

>c

>c

p

>c

w

This argument holds no matter which vertex you label as p.

Here, we set p = v4.

89 of 120

Guaranteed Optimality

Claim: distTo[v1] is optimal, and thus future relaxations will fail. Why?

  • distTo[p] distTo[v1] for all p, therefore
  • distTo[p] + wdistTo[v1]

S

s

0

v2

v1

>c

c

>c

c

v3

>c

>c

>c

v4

>c

w

p

>c

This argument holds no matter which vertex you label as p.

Here, we set p = some deeper vertex. Cost is still >c because you reach p via v3.

90 of 120

Negative Edges

Dijkstra’s Algorithm:

  • Visit vertices in order of best-known distance from source. On visit, relax every edge from the visited vertex.

Dijkstra’s can fail if graph has negative weight edges. Why?

  • The idea of visiting vertices in order of distance no longer makes sense.

Algorithm #2 (dummy nodes) visits:� every node distance 1 away,�then every node distance 2 away,�then every node distance 3 away, etc.

Add negatively many dummy nodes??

Nodes that are distance -1 away??

91 of 120

Negative Edges

Dijkstra’s Algorithm:

  • Visit vertices in order of best-known distance from source. On visit, relax every edge from the visited vertex.

Dijkstra’s can fail if graph has negative weight edges. Why?

  • Relaxation of already visited vertices can succeed.

X

Y

-67

82

101

92 of 120

Negative Edges

Dijkstra’s Algorithm:

  • Visit vertices in order of best-known distance from source. On visit, relax every edge from the visited vertex.

Dijkstra’s can fail if graph has negative weight edges. Why?

  • Relaxation of already visited vertices can succeed.

X

Y

-67

82

101

34

Even though vertex Y has greater distTo at the time of its visit, it is still able to modify the distTo of a visited (white) vertex.

93 of 120

Runtime Analysis

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

94 of 120

Dijkstra’s Algorithm Runtime

Priority Queue operation count, assuming binary heap based PQ:

  • add: V, each costing O(log V) time.
  • removeSmallest: V, each costing O(log V) time.
  • changePriority: E, each costing O(log V) time.

Overall runtime: O(V*log(V) + V*log(V) + E*logV).

  • Assuming E > V, this is just O(E log V) for a connected graph.

# Operations

Cost per operation

Total cost

PQ add

V

O(log V)

O(V log V)

PQ removeSmallest

V

O(log V)

O(V log V)

PQ changePriority

E

O(log V)

O(E log V)

95 of 120

A* Idea and Demo

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

96 of 120

Single Target Dijkstra’s

Is this a good algorithm for a navigation application?

  • Will it find the shortest path?
  • Will it be efficient?

97 of 120

The Problem with Dijkstra’s

Dijkstra’s will explore every place within nearly two thousand miles of Denver before it locates NYC.

98 of 120

The Problem with Dijkstra’s

We have only a single target in mind, so we need a different algorithm. How can we do better?

99 of 120

How can we do Better?

Explore eastwards first?

100 of 120

Introducing A*

Simple idea:

  • Visit vertices in order of d(Denver, v) + h(v, goal), where h(v, goal) is an estimate of the distance from v to our goal NYC.
  • In other words, look at some location v if:

Compared to Dijkstra’s which only considers d(source, v).

    • We know already know the fastest way to reach v.
    • AND we suspect that v is also the fastest way to NYC taking into account the time to get to v.

Example: Henderson is farther than Englewood, but probably overall better for getting to NYC.

101 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

1

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B ∞ -

C ∞ -

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(B: ∞), (C: ∞), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

h(v, goal) is arbitrary. In this example, it’s the min weight edge out of each vertex.

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

102 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

1

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(B: 5), (C: 16), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

2

1

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

103 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D ∞ -

E ∞ -

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(C: 16), (D: ∞), (E: ∞), (F: ∞), (G: ∞)]

4

0

1

1

2

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

104 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(E: 6), (D: 15), (C: 16), (F: ∞), (G: ∞)]

4

0

1

1

2

5

13

Which vertex is removed next?

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

105 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F ∞ -

G ∞ -

5

2

1

15

3

2

11

5

1

1

Fringe: [(D: 15), (C: 16), (F: ∞), (G: ∞)]

4

0

1

1

2

5

13

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

  • Give distTo, edgeTo, and fringe after relaxation

106 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: [(G: 10), (D: 15), (C: 16), (F: ∞)]

4

0

1

1

2

5

13

10

9

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

107 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

Fringe: [(G: 10), (D: 15), (C: 16), (F: ∞)]

4

0

1

1

2

5

13

10

9

Next vertex to be dequeued is our target, so we’re done!

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

108 of 120

A* Demo, with s = 0, goal = 6.

h(v, goal)

1

3

15

2

1

0

B

C

D

E

F

G

A

s

Node distTo edgeTo

A 0 -

B 2 A

C 1 A

D 13 B

E 5 B

F 9 E

G 10 E

5

2

1

15

3

2

11

5

1

1

4

0

1

1

2

5

13

10

9

Observations:

  • Not every vertex got visited.
  • Result is not a shortest paths tree for vertex zero (path to 3 is suboptimal!), but that’s OK because we only care about path to 6.

Insert all vertices into fringe PQ, storing vertices in order of d(source, v) + h(v, goal).

Repeat: Remove best vertex v from PQ, and relax all edges pointing from v.

109 of 120

A* Heuristic Example

How do we get our estimate?

  • Estimate is an arbitrary heuristic h(v, goal).
  • heuristic: “using experience to learn and improve”
  • Doesn’t have to be perfect!

For the map to the right, what could we use?

110 of 120

A* Heuristic Example

How do we get our estimate?

  • Estimate is an arbitrary heuristic h(v, goal).
  • heuristic: “using experience to learn and improve”
  • Doesn’t have to be perfect!

For the map to the right, what could we use?

  • As-the-crow-flies distance to NYC.

/** h(v, goal) DOES NOT CHANGE as algorithm runs. */

public method h(v, goal) {

return computeLineDistance(v.latLong, goal.latLong);

}

111 of 120

A* vs. Dijkstra’s Algorithm

http://qiao.github.io/PathFinding.js/visual/

Note, if edge weights are all equal (as here), Dijkstra’s algorithm is just breadth first search.

This is a good tool for understanding distinction between order in which nodes are visited by the algorithm vs. the order in which they appear on the shortest path.

  • Unless you’re really lucky, vastly more nodes are visited than exist on the shortest path.

112 of 120

A* Heuristics (CS188 Preview)

Lecture 24, CS61B, Fall 2023

Shortest Paths:

  • Why BFS Doesn’t Work
  • Goal: The Shortest Paths Tree

Dijkstra’s Algorithm

  • Some Bad Algorithms
  • Dijkstra’s Algorithm
  • Why Dijkstra’s is Correct
  • Runtime Analysis

A*

  • A* Idea and Demo
  • A* Heuristics (CS188 Preview)

113 of 120

Impact of Heuristic Quality

Suppose we throw up our hands and say we don’t know anything, and just set h(v, goal) = 0 miles. What happens?

What if we just set h(v, goal) = 10000 miles?

A* Algorithm:

Visit vertices in order of d(Denver, v) + h(v, goal), where h(v, goal) is an estimate of the distance from v to NYC.

114 of 120

Impact of Heuristic Quality

Suppose we throw up our hands and say we don’t know anything, and just set h(v, goal) = 0 miles. What happens?

  • We just end up with Dijkstra’s algorithm.

What if we just set h(v, goal) = 10000 miles?

  • We just end up with Dijkstra’s algorithm.

A* Algorithm:

Visit vertices in order of d(Denver, v) + h(v, goal), where h(v, goal) is an estimate of the distance from v to NYC.

115 of 120

Impact of Heuristic Quality

Suppose you use your impressive geography knowledge and decide that the midwestern states of Illinois and Indiana are in the middle of nowhere: h(Indianapolis, goal)=h(Chicago, goal)=...=100000.

  • Is our algorithm still correct or does it just run slower?

116 of 120

Impact of Heuristic Quality

Suppose you use your impressive geography knowledge and decide that the midwestern states of Illinois and Indiana are in the middle of nowhere: h(Indianapolis, goal)=h(Chicago, goal)=...=100000.

  • Is our algorithm still correct or does it just run slower?
    • It is incorrect. It will fail to find the shortest path by dodging Illinois.

117 of 120

Heuristics and Correctness (EXTRA: Beyond Course Scope)

For our version of A* to give the correct answer, our A* heuristic must be:

  • Admissible: h(v, NYC) ≤ true distance from v to NYC.
  • Consistent: For each neighbor of w:
    • h(v, NYC) ≤ dist(v, w) + h(w, NYC).
    • Where dist(v, w) is the weight of the edge from v to w.

This is an artificial intelligence topic, and is beyond the scope of our course.

  • We will not discuss these properties beyond their definitions. See CS188 which will cover this topic in considerably more depth.
  • You should simply know that the choice of heuristic matters, and that if you make a bad choice, A* can give the wrong answer.
  • You will not be expected to tell us whether a given heuristic is admissible or consistent unless we define these terms on an exam.

Our heuristic was inadmissible and inconsistent.

118 of 120

Consistency and Admissibility (EXTRA: Beyond Course Scope)

All consistent heuristics are admissible.

  • ‘Admissible’ means that the heuristic never overestimates.

Admissibility and consistency are sufficient conditions for certain variants of A*.

  • If heuristic is admissible, A* tree search yields the shortest path.
  • If heuristic is consistent, A* graph search yields the shortest path.
  • These conditions are sufficient, but not necessary.

Heuristics that Yield Correct NYC Route

Admissible

Consistent

Our version of A* is called “A* graph search”. There’s another version called “A* tree search”. You’ll learn about it in 188.

119 of 120

Summary: Shortest Paths Problems

Single Source, Multiple Targets:

  • Can represent shortest path from start to every vertex as a shortest paths tree with V-1 edges.
  • Can find the SPT using Dijkstra’s algorithm.

Single Source, Single Target:

  • Dijkstra’s is inefficient (searches useless parts of the graph).
  • Can represent shortest path as path (with up to V-1 vertices, but probably far fewer).
  • A* is potentially much faster than Dijkstra’s.
    • Consistent heuristic guarantees correct solution.

120 of 120

Graph Problems

Problem

Problem Description

Solution

Efficiency

paths

Find a path from s to every reachable vertex.

DepthFirstPaths.java

Demo

O(V+E) time

Θ(V) space

shortest paths

Find the shortest path from s to every reachable vertex.

BreadthFirstPaths.java

Demo

O(V+E) time

Θ(V) space

shortest weighted paths

Find the shortest path, considering weights, from s to every reachable vertex.

DijkstrasSP.java

Demo

O(E log V) time

Θ(V) space

shortest weighted path

Find the shortest path, consider weights, from s to some target vertex

A*: Same as Dijkstra’s but with h(v, goal) added to priority of each vertex.

Demo

Time depends on heuristic.

Θ(V) space