Shortend OH today
Example 1: Computer Networks
Example 2: Social Networks
Example 3: State Space of a Game
What do these examples have in common?
A graph $G = (V, E)$ consists of
Example. $V = {1, 2, 3, 4, 5}$, $E = {(1, 2), (2, 3), (3, 4), (4, 5), (5, 1), (1, 3)}$
Computer Network
$V = $
$E = $
Social Network
$V = $
$E = $
Tic-Tac-Toe
$V = $
$E = $
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 presentremoveVertex(u)
remove u
and edges containing u
from graphaddEdge(u, v)
add an edge from u
to v
if not already presentremoveEdge(u, v)
remove edge from u
to v
if present(Can have others too…)
addVertex(1)
addVertex(2)
addVertex(3)
addVertex(4)
addEdge(1, 2)
addEdge(2, 3)
addEdge(2, 4)
addEdge(3, 4)
neighbors(2)
Question. How could we represent a graph?
Maintain a Map<E, List<E>>
:
E
)List<E>
s of verticesHashMap<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()
…neighbors(u)
return a List of vertices adjacent to u
… boolean adjacent(u, v)
return true
if u
and v
are adjacent (i.e., (u, v)
is an edge)
… 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
Suppose we are given an arbitrary vertex $v$ in a graph. How could we determine if another vertex $u$ is reachable from $v$?
Idea. Start at $v$, and walk until you’ve either explored whole graph or find $u$
When visiting a node:
Question. How do we know if search has failed?
What information do we need to maintain to perform DFS?
What ADTs/DSs could we use to maintain that information?
Set<E> visited
of visited nodesStack<E> active
of active nodesboolean 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;
}
How could we modify dfsFind
to return the path from v
to u
(if found)?
What might be undesireable about the path found by DFS?
How could we find the shortest path from v
to u
(if any)?
Idea. Start at $v$, and look at other nodes in order of increasing distance from $v$
Question. How to do this?
What information do we need to maintain to perform BFS?
What ADTs/DSs could we use to maintain that information?
Set<E> visited
of visited nodesQueue<E> active
of active nodesboolean 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;
}
Why does BFS find u
along the shortest path from v
to u
?
How could we modify bfsFind
to return the shortest path from v
to u
?