1 of 39

Pre-Announcement

Brenley for Gill Tract Community Farm

  • Community Farm in Albany
  • Affiliated with University
  • Open hours Sunday - Thursday.
    • Take organic veggies away with you for volunteering.
    • gilltractfarm.org
    • contact@gilltractfarm.org
  • Volunteering means:
    • Planting and destroying plants.

2 of 39

Announcements

Pre-spring Break Extra Credit Survey due Friday at 11:59 PM.

  • Sorry for the delay, had some issues with creating a big enough survey in Google Forms to handle potential feedback for all TAs.

Lab due this Friday will be released today for those of you travelling who want to get it in early.�

3 of 39

CS61B

Lecture 26: Graphs

  • Intro
  • Graph Implementations
  • Depth First Traversal

4 of 39

Graph

Graph: A set of nodes (a.k.a. vertices) connected pairwise by edges.�

5 of 39

Graph Types

a

b

d

c

a

b

d

c

e

a

b

d

c

a

b

d

c

Acyclic:

Cyclic:

Directed

Undirected

With Edge Labels

b

d

c

e

a

1

2

3

1

6 of 39

Graph Terminology

  • Graph:
    • Set of vertices, a.k.a. nodes.
    • Set of edges: Pairs of vertices.
    • Vertices with an edge between are adjacent.
    • Optional: Vertices or edges may have labels (or weights).
  • A path is a sequence of vertices connected by edges.
  • A cycle is a path whose first and last vertices are the same.
    • A graph with a cycle is ‘cyclic’.
  • Two vertices are connected if there is a path between them. If all vertices are connected, we say the graph is connected.

Figure from Algorithms 4th Edition

7 of 39

Some Graph-Processing Problems

s-t Path. Is there a path between vertices s and t?

Shortest s-t Path. What is the shortest path between vertices s and t?

Cycle. Does the graph contain any cycles?

Euler Tour. Is there a cycle that uses every edge exactly once?

Hamilton Tour. Is there a cycle that uses every vertex exactly once?

Connectivity. Is the graph connected, i.e. is there a path between all vertex pairs?

Biconnectivity. Is there a vertex whose removal disconnects the graph?

Planarity. Can you draw the graph on a piece of paper with no crossing edges?

Isomorphism. Are two graphs isomorphic (the same graph in disguise)?

Graph problems: Unobvious which are easy, hard, or computationally intractable.

8 of 39

Graph Example: The Paris Metro

This subway map of Paris is:

  • Undirected
  • Connected
  • Cyclic (not a tree!)
  • Vertex-labeled��

9 of 39

Graph Example: BART

Is the BART graph a tree?��

10 of 39

Nodes: Cities. Edge Weights: ~Number of friends between cities

11 of 39

Nodes: Scientific Journals.

  • Label: AAT classification (the topic that it covers)

Edges:

  • Based on clickthrough data.
  • Clickthrough from v to w means that someone reading an article in journal v clicked on a link to an article in journal w.
  • Edge assigned from v to w if clickthrough rate from v to w is above some arbitrary threshold.

12 of 39

Edge captures ‘is-a-type-of’ relationship. Example: descent is-a-type-of movement.

13 of 39

Graph Representations

14 of 39

Common Simplification: Integer Vertices

Common convention: Number nodes irrespective of label, and use number throughout the graph implementation. To lookup a vertex by label, use a Map<Label, Integer>.

Austin

Dallas

Houston

0

1

2

Intended graph.

What you get.

Map<String, Integer>

Austin: 0

Dallas: 1

Houston: 2

15 of 39

Graph API

Using a graph in Java:

public class Graph {

public Graph(int V): Create empty graph with v vertices

public void addEdge(int v, int w): add an edge v-w

Iterable<Integer> adj(int v): vertices adjacent to v

int V(): number of vertices

int E(): number of edges

...

16 of 39

Graph API

Using a graph in Java:

Example client:

public class Graph {

public Graph(int V): Create empty graph with v vertices

public void addEdge(int v, int w): add an edge v-w

Iterable<Integer> adj(int v): vertices adjacent to v

int V(): number of vertices

int E(): number of edges

...

/** degree of vertex v in graph G */

public static int degree(Graph G, int v) {

int degree = 0;

for (int w : G.adj(v)) {

degree += 1;

}

return degree; }

(degree = # edges)

degree(G, 2) = 2

1

3

2

17 of 39

Graph Representations

0

1

2

  • Representation 1: Adjacency Matrix.

0

1

2

0

0

1

1

1

0

0

1

2

0

0

0

0

1

3

2

0

1

2

3

0

0

1

0

0

1

1

0

1

0

2

0

1

0

1

3

0

0

1

0

For undirected graph: Each edge is represented twice in the matrix. Simplicity at the expense of space.

s

t

v

w

18 of 39

Graph Printing Runtime: http://shoutkey.com/from

What is the order of growth of the running time of the following code if the graph uses an adjacency-matrix representation, where V is the number of vertices, and E is the total number of edges?

  1. Θ(V)
  2. Θ(V + E)
  3. Θ(V2)
  4. Θ(V*E)

How much time does adj take?

How many adj calls?

0

1

2

3

0

0

1

0

0

1

1

0

1

0

2

0

1

0

1

3

0

0

1

0

0

1

3

2

19 of 39

PollEverywhere: pollEv.com/jhug or text “jhug” to 37607

What is the order of growth of the running time of the following code if the graph uses an adjacency-matrix representation, where V is the number of vertices, and E is the total number of edges.

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

How much time does adj take?

  • Θ(V) worst case.

How many adj calls?

  • Θ(V) calls.

0

1

2

3

0

0

1

0

0

1

1

0

1

0

2

0

1

0

1

3

0

0

1

0

0

1

3

2

20 of 39

PollEverywhere: pollEv.com/jhug or text “jhug” to 37607

What is the order of growth of the running time of the following code if the graph uses an adjacency-matrix representation, where V is the number of vertices, and E is the total number of edges.

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

�What does G.adj(1) return?

  • {0, 2}

0

1

2

3

0

0

1

0

0

1

1

0

1

0

2

0

1

0

1

3

0

0

1

0

0

1

3

2

21 of 39

More Graph Representations

Representation 2: Edge Sets: Collection of all edges.

  • Example: HashSet<Edge>, where each Edge is a pair of ints.

0

1

2

{(0, 1), (0, 2), (1, 2)}

22 of 39

More Graph Representations

Representation 3: Adjacency lists.

  • Common approach: Maintain array of lists indexed by vertex number.
  • Most popular approach for representing graphs.

0

1

2

0

1

2

[1, 2]

[2]

23 of 39

Graph Printing Runtime: http://shoutkey.com/squeal

What is the order of growth of the running time of the following code if the graph uses an adjacency-list representation, where V is the number of vertices, and E is the total number of edges?

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

How much time does adj take?

How many adj calls?

a

b

c

0

1

2

[1, 2]

[2]

24 of 39

Graph Printing Runtime: http://shoutkey.com/squeal

What is the order of growth of the running time of the following code if the graph uses an adjacency-list representation, where V is the number of vertices, and E is the total number of edges?

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

How much time does adj take?

  • Θ(1), G.adj(1), we just return the list itself!

How many adj calls?

  • Θ(V)

a

b

c

0

1

2

[1, 2]

[2]

25 of 39

Graph Printing Runtime: http://shoutkey.com/squeal

What is the order of growth of the running time of the following code if the graph uses an adjacency-list representation, where V is the number of vertices, and E is the total number of edges?

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

�If we count adj as our cost model: Θ(V)

If we count prints: Θ(E)

a

b

c

0

1

2

[1, 2]

[2]

26 of 39

Graph Printing Runtime: http://shoutkey.com/squeal

What is the order of growth of the running time of the following code if the graph uses an adjacency-list representation, where V is the number of vertices, and E is the total number of edges?

  • Θ(V)
  • Θ(V + E)
  • Θ(V2)
  • Θ(V*E)

a

b

c

0

1

2

[1, 2]

[2]

27 of 39

Graph Representations

Runtime of some basic operations for each representation:

In practice, adjacency lists are most common.

  • Many graph algorithms rely heavily on adj(s).
  • Most graphs are sparse (not many edges in each bucket).

idea

addEdge(s, t)

adj(s)

printgraph()

hasEdge(s, t)

space used

adjacency matrix

Θ(1)

Θ(V)

Θ(V2)

Θ(1)

Θ(V2)

list of edges

Θ(1)

Θ(E)

Θ(E)

Θ(E)

Θ(E)

adjacency list

Θ(1)

Θ(1)

Θ(V+E)

Θ(degree(v))

Θ(E+V)

Note: These operations are not part of the Graph class’s API.

28 of 39

Bare-Bones Undirected Graph Implementation

Cannot create array of anything involving generics, so have to use weird cast as with project 1A.

public class Graph {

private final int V; private List<Integer>[] adj;

public Graph(int V) {

this.V = V;

adj = (List<Integer>[]) new ArrayList[V];

for (int v = 0; v < V; v++) {

adj[v] = new ArrayList<Integer>();

}

}

public void addEdge(int v, int w) {

adj[v].add(w); adj[w].add(v);

}

public Iterable<Integer> adj(int v) {

return adj[v];

}

}

29 of 39

Depth-First Traversal

30 of 39

Maze Traversal / s-t Path

Suppose we want to know if there exists a path from vertex s=0 to vertex t=7. What is wrong with the following recursive algorithm for connected(s, t)?

  • Does s == t? If so, return true.
  • Otherwise, check all of s’s children for connectivity to t.

Example:

  • connected(0, 7):
    • Does 0 == 7? No, so...
    • if (connected(1, 7)) return true;
    • return false;

  • connected(1, 7): ...

1

2

3

4

5

6

7

8

0

s

t

31 of 39

Improving Our Connectivity Algorithm

Goal: Search for a path from s to t, but visit each vertex at most once. To do this, we can mark each vertex as we search. Resulting algorithm for connected(s, t) is as follows:

  • Mark s.
  • Does s == t? If so, return true.
  • Check all of s’s unmarked neighbors for connectivity to t.

Recursive connectivity demo.

1

2

3

4

5

6

7

8

0

s

t

32 of 39

Depth First Traversal

This idea of exploring the entire subgraph for each child is known as Depth First Traversal.

  • Ex. Visit all of 1’s children before we visit any of 3’s.

1

2

3

4

5

6

7

8

0

33 of 39

Or a more visceral example: https://xkcd.com/761/

34 of 39

Depth First Search Implementation

Common design pattern in graph algorithms: Decouple type from processing algorithm.

  • Create a graph object.
  • Pass the graph to a graph-processing method (or constructor) in a client class.
  • Query the client class for information.

public class Paths {

public Paths(Graph G, int s): Find all paths from G

boolean hasPathTo(int v): is there a path from s to v?

Iterable<Integer> pathTo(int v): path from s to v (if any)

}

Paths.java

35 of 39

Example Usage

Start by calling: Paths P = new Paths(G, 0);

  • P.hasPathTo(3); //returns true
  • P.pathTo(3); //returns {0, 1, 4, 3}

Paths.java

public class Paths {

public Paths(Graph G, int s): Find all paths from G

boolean hasPathTo(int v): is there a path from s to v?

Iterable<Integer> pathTo(int v): path from s to v (if any)

}

36 of 39

Implementing Paths With Depth First Search

To visit a vertex v:

  • Mark vertex v.
  • Recursively visit all unmarked vertices adjacent to v.

Data Structures:

  • boolean[] marked
  • int[] edgeTo
    • edgeTo[4] = 1, means we went from 1 to 4.

Paths.java

public class Paths {

public Paths(Graph G, int s): Find all paths from G

boolean hasPathTo(int v): is there a path from s to v?

Iterable<Integer> pathTo(int v): path from s to v (if any)

}

37 of 39

DepthFirstPaths

38 of 39

DepthFirstPaths, Recursive Implementation

public class DepthFirstPaths {

private boolean[] marked;

private int[] edgeTo;

private int s;

public DepthFirstPaths(Graph G, int s) {

...

dfs(G, s);

}

private void dfs(Graph G, int v) {

marked[v] = true;

for (int w : G.adj(v)) {

if (!marked[w]) {

edgeTo[w] = v;

dfs(G, w);

}

}

}

marked[v] is true iff v connected to s

edgeTo[v] is previous vertex on path from s to v

find vertices connected to s.

not shown: data structure initialization

recursive routine does the work and stores results in an easy to query manner!

Question: How would we write hasPathTo(v)?

39 of 39

DepthFirstPaths Summary

Demo: DepthFirstPaths

Properties of Depth First Search:

  • Guaranteed to reach every node.
  • Runs in O(V + E) time.
    • Analysis next time, but basic idea is that every edge is used at most once, and total number of vertex considerations is equal to number of edges.
    • Runtime may be faster for problems which quit early on some stopping condition (for example connectivity).�