Lecture 16 notes

Graphs: basic definitions and notation
Definition A (undirected, unweighted) graph is a pair G = (V, E), where
V = {v1, v2, ..., vn} is a set of vertices, and E <= V2 , where
V2 = {{v1, v2}, {v1, v3}, ... , {v1, vn}, ... , {vn-1, vn}} is an unordered product of V,
i.e. a set of all two element subsets of V defining the set of all possible edges
of the graph, G.
Example G = (V, E) where V = {a, b, c, d} and E = V2
a
b
d
c
c
d
a
b
Definition Graph G = (V, E) with all possible edges present (i.e. E = V2) is
called a complete graph.
Example Consider the following graph, where nodes represent cities, and
edges show if there is a direct flight between each pair of cities.
CHG
SF
HTD
OAK
ATL
LA
SD
V = {SF, OAK, CHG, HTD, ATL, LA, SD}
E = {{SF, HTD}, {SF, CHG}, {SF, LA}, {SF, SD}, {SD, OAK}, {CHG, LA},
{LA, OAK}, {LA, ATL}, {LA, SD}, {ATL, HTD}, {SD, ATL}}
Definition A subgraph of a graph G = (V, E) is a graph G’ = (V’, E’), where
V’<= V and E’<= E.
Definition A graph with a small number of edges present ( E <= V log V) is
called a sparse graph.
Definition A graph with E > V log V is called a dense graph.
Definition Let G = (V, E), and x, y are two vertices. We say that:
• x and y are adjacent if {x, y} belongs to E;
• x and y are called incident to the edge {x, y} (for brevity, we will write xy
instead of {x, y}).
To describe the relationship of adjacency in a graph, we use adjacency
matrix. Let V = {a, b, c, d, e, f, g} and E = {ab, cd, fg, bg, af}. The adjacency
matrix describing this graph is the following:
a
b
c
d
e
f
g
a
0
1
0
0
0
1
0
b
1
0
0
0
0
0
1
c
0
0
0
1
0
0
0
d
0
0
1
0
0
0
0
e
0
0
0
0
0
0
0
f
1
0
0
0
0
0
1
g
0
1
0
0
0
1
0
we assume that vertices cannot be adjacent to themselves
Definition Let G = (V, E), and v1, ... , vn belong to V are such that vi vi+1
belongs to E for 1 <= i <= n-1. Then, the sequence v1, v1v2, v2, v2v3, v3, v3v4, ...,
vn-1, vn-1vn, vn is called:
• a walk from v1 to vn. We will write for brevity v1 v2 v3 ... vn;
• if the edges are all distinct, we call it a trail from v1 to vn;
• if the vertices are all distinct (except possible for v1 and vn), it is called a
path between v1 and vn;
• a walk, trail or path is called trivial if it consists of a single vertex,
otherwise it is called non-trivial;
• a walk, trail or path is called closed if v1 = vn, otherwise it is called
open;
• a non-trivial closed trail or path is called a cycle.
Definition A graph is called connected if there is a path from each node to
every other node in the graph.
Definition Let G = (V, E) be a connected graph, and T = (V, E’) be a tree
with the same vertex set, V, but E’ is a subset of E. Then T is called a
spanning tree of G.
Example:
a graph
and its spanning tree
The Graph ADT
Definition A graph, G, is a data structure comprised by two sets of objects,
nodes and edges, where nodes store data and edges indicate relationships
between the data stored in the nodes.
Operations (methods) on graphs:
addEdge(v1, v2)
Returns G with new edge v1v2 added
removeEdge(v1, v2) Returns G with edge v1v2 removed
edge(v1, v2)
Returns true if there is an edge between v1 and v2
vertices()
Returns an enumeration all vertices in G
edges()
Returns an enumeration of all edges in G
numVertices()
Returns the number of vertices in G
numEdges()
Returns the number of edges in G
degree(v)
Returns the degree of v
adjacentVertices(v) Returns an enumeration of the vertices adjacent to v
incidentEdges(v)
Returns an enumeration of edges incident to v
Representation of graphs as an adjacency matrix
The easiest way to represent a graph is by means of its adjacency matrix. For
unweighted undirected graphs, the adjacency matrix V(vij) is an n x n matrix,
where
1, if vivj belongs to E
vij =
0, otherwise
for 1 <= i, j <= n, and vivi belongs to E for all i.
Example Consider the following graph
a
h
i
g
b
d
f
e
c
j
k
l
m
Example (contd.)
The adjacency matrix of the example graph is the following:
a
b
c
d
e
f
g
h
i
j
k
l
m
a
b
c
d
e
f
g
h
i
j
k
l
m
1
1
1
0
0
1
1
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
0
0
0
0
0
0
0
0
0
0
1
1
1
1
0
0
0
0
0
0
1
0
0
1
1
1
0
0
0
0
0
0
0
1
0
0
0
1
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
0
0
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
0
0
0
0
0
1
0
1
1
0
0
0
0
0
0
0
0
0
1
0
1
1
Because vivi belongs to E for all i.
Representation of graphs as adjacency lists
Each node has an adjacency list associated with it, which contains all of the
nodes adjacent to that node. Our example graph is described by means of the
following adjacency lists:
a
b
c
d
e
f
g
h
i
j
k
l
m
f
a
a
f
g
a
e
i
h
k
j
j
j
e
f
e
a
m
l
d
d
c
b
l
m
g
Here edges were assumed to have appeared in the following order: ag, ab, ac,
lm, jm, jl, jk, ed, fd, hi, fe, af, ge.
Graph traversals
Given graph G, we want to systematically visit every node, and check every
edge. The two main traversals are:
1
Depth-first traversal. Assume start is a node in the graph, where our
traversal begins. Then, each node reachable from start is visited in
the following order:
1) start is visited, then
2) the first node adjacent to start, and recursively all nodes adjacent
to that node, then
3) the second node adjacent to start, and recursively all nodes
adjacent to that node, then
...
7) the n-th node adjacent to start, and recursively all nodes adjacent
to it.
Graph traversals (contd.)
2
Breadth-first traversal. Assume start is a node in the graph, where
our traversal begins. Then, each node reachable from start is visited in
the following order:
1) start is visited, then
2) all nodes adjacent to start, then
3) all nodes adjacent to the nodes adjacent to start, etc.
Example: Assume the edges arrive in the following order: ad, ac, ab, bc, bd.
Let the start node be a. b is the first node
d
a
adjacent to a, and d is the first node adjacent to b.
Then the depth-first traversal visits the nodes in the
following order: a, b, d, c. The breadth-first traversal
c
b
visits the nodes as follows: a, b, c, d given that
b is the first node adjacent to a, c is the second node adjacent to a, and d is the
third node adjacent to a. That is, traversals depend on assumptions about
node connections.
Depth-first traversal: the algorithm
Algorithm depthFirstTraversal (G, start)
Input: a graph, G, and a node, start, in G.
Output: all nodes in G visited.
boolean[] visited = new boolean[numberOfNodes]
for k := 1 to numberOfNodes
visited[k] := false
searchFrom(start,visited)
Algorithm searchFrom (node, visited)
Input: a node, start, in a graph.
Output: start and all nodes reachable from start marked as visited.
start.displayGraphNode()
visited[start] := true
for k := 1 to numberOfNodes
if (! visited[k] && start.edge(k))
searchFrom(k,visited)
Breadth-first traversal: the algorithm
Algorithm breadthFirstTraversal (G, start)
Input: a graph, G, and a node, start, in G.
Output: all nodes in G visited.
boolean[] inQueue = new boolean[numberOfNodes]
Queue nodesToVisit = new Queue(numberOfNodes)
for k := 1 to numberOfNodes
inQueue[k] = false
nodesToVisit.enqueue(start)
inQueue[start] = true
while (! nodesToVisit.empty())
graphNode node = nodesToVisit.dequeue()
node.displayGraphNode()
for k:=1 to numberOfNodes
if (! inQueue[k] and node.edge(k))
nodesToVisit.enqueue(k)
inQueue[k] := true