Lecture 24: Graphs, Part I

Announcement

Shortend OH today

  • Have to leave by 3:00

Overview

  1. Motivating Examples
  2. Graph Definition
  3. The Graph ADT
  4. Searching a Graph

Last Time

Example 1: Computer Networks

Example 2: Social Networks

Example 3: State Space of a Game

Commonalities of Examples

What do these examples have in common?

  1. Entities or locations
  2. Connections between entities

Mathematical Formalism: Graphs

A graph $G = (V, E)$ consists of

  • a set $V$ of vertices (a.k.a. nodes) $V = {v_1, v_2,\ldots,v_n}$
  • a set $E$ of edges, where each edge is a pair of vertices

Example. $V = {1, 2, 3, 4, 5}$, $E = {(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (1, 3)}$

Graph Terminology

  1. If $E$ contains $(u, v)$ then $u$ and $v$ are neighbors or adjacent
  2. Two variants:
    • undirected graph if $u$ is $v$’s neighbor, then $v$ is $u$’s neighbor
    • directed graph $(u, v)$ an edge doesn’t imply $(v, u)$ is an edge

Previous Examples as Graphs

Computer Network

  • $V = $

  • $E = $

Social Network

  • $V = $

  • $E = $

Tic-Tac-Toe

  • $V = $

  • $E = $

Graphs We’ve Seen Already?

Graph ADT and Operations

How to build & use graphs?

  • boolean adjacent(u, v) return true if u and v are adjacent (i.e., (u, v) is an edge)
  • neighbors(u) return a List of vertices adjacent to u
  • addVertex(u) add a vertex to set of vertices, if not already present
  • removeVertex(u) remove u and edges containing u from graph
  • addEdge(u, v) add an edge from u to v if not already present
  • removeEdge(u, v) remove edge from u to v if present

(Can have others too…)

Example

addVertex(1)

addVertex(2)

addVertex(3)

addVertex(4)

addEdge(1, 2)

addEdge(2, 3)

addEdge(2, 4)

addEdge(3, 4)

neighbors(2)

Graph Representation

Question. How could we represent a graph?

  • What ADTs should/could we use?

Adjacency List Representation

Maintain a Map<E, List<E>>:

  • Keys are vertices (use datatype E)
  • Vertices are List<E>s of vertices

Implementation with Java Built-ins

HashMap<K, V> map:

  • containsKey(K x)
  • get(K x)
  • put(K x, V y)
  • remove(K x)

ArrayList:

  • add(E x)
  • contains(E x)
  • remove(E x)
  • get(int i)
  • size()

How to…

neighbors(u) return a List of vertices adjacent to u

How to…

boolean adjacent(u, v) return true if u and v are adjacent (i.e., (u, v) is an edge)

How to…

addVertex(u) add a vertex to set of vertices, if not already present

How to…

removeVertex(u) remove u and edges containing u from graph

How to…

addEdge(u, v) add an edge from u to v if not already present

How to…

removeEdge(u, v) remove edge from u to v if present

Question

Suppose we are given an arbitrary vertex $v$ in a graph. How could we determine if another vertex $u$ is reachable from $v$?

  • Is there a path from $u$ to $v$ in $G$?

Depth First Strategy

Idea. Start at $v$, and walk until you’ve either explored whole graph or find $u$

When visiting a node:

  • check if node is $u$
  • if not, pick an unvisited neighbor and go there
  • if no unvisited neighbor, backtrack until you reach a node with an unvisited neighbor

Question. How do we know if search has failed?

DFS Illustrated

Implementing DFS

What information do we need to maintain to perform DFS?

What ADTs/DSs could we use to maintain that information?

DFS Implementation

  • Set<E> visited of visited nodes
  • Stack<E> active of active nodes
boolean dfsFind(E v, E u) {
  visited.add(v);
  active.push(v)
  
  while (active.size() > 0) {
  
    E cur = active.peek();	
    if (cur.equals(u)) return true;
	  
    for (x : cur.neighbors()) {
      if (!visited.contains(x)) {
        visited.add(x);
        active.push(x);
        break;
      }
    }
  }
  return false;
}

Question 1

How could we modify dfsFind to return the path from v to u (if found)?

Question 2

What might be undesireable about the path found by DFS?

Question 3

How could we find the shortest path from v to u (if any)?

Breadth First Strategy

Idea. Start at $v$, and look at other nodes in order of increasing distance from $v$

Question. How to do this?

  • check $v$
  • check $v$’s neighbors
  • check $v$’s neighbors’ neighbors

BFS Illustrated

Implementing BFS

What information do we need to maintain to perform BFS?

What ADTs/DSs could we use to maintain that information?

BFS Implementation

  • Set<E> visited of visited nodes
  • Queue<E> active of active nodes
boolean bfsFind(E v, E u) {
  visited.add(v);
  active.push(v)
  
  while (active.size() > 0) {
  
    E cur = active.remove();	
    if (cur.equals(u)) return true;
	  
    for (x : cur.neighbors()) {
      if (!visited.contains(x)) {
        visited.add(x)
        active.add(x);
      }
    }
  }
  return false;
}

Question 1

Why does BFS find u along the shortest path from v to u?

Question 2

How could we modify bfsFind to return the shortest path from v to u?