Elementary Graph Algorithmsumsl.edu/~adhikarib/cs4130-fall2017/slides/05... · Elementary Graph...

Post on 22-Jul-2020

8 views 0 download

Transcript of Elementary Graph Algorithmsumsl.edu/~adhikarib/cs4130-fall2017/slides/05... · Elementary Graph...

Elementary Graph Algorithms[for graphs with no edge weights]

Course: CS 5130 - Advanced Data Structures and Algorithms Instructor: Dr. Badri Adhikari

Representations of graphA directed or undirected graph G = (V, E) can be represented as

(a) a collection of adjacency lists, or(b) an adjacency matrix.

Adjacency-list representation provides a compact way to represent sparse graphs - those for which |E| is much less than |V2|. More common method.

Adjacency-matrix representation is preferred (a) when the graph is dense - |E| is close to |V2|, or (b) when we need to be able to quickly tell if there is an edge connecting two given vertices.

Adjacency-list representationThe adjacency-list representation of a graph G = (V, E) consists of an array Adj of |V| lists, one for each vertex.

For each u ∈ V, the adjacency-list Adj[u] contains all the vertices v such that there is an edge (u, v) ∈ E. That is, Adj[u] consists of all the vertices adjacent to u in G.

In pseudocodes, Adj is an attribute of G. For example, G.Adj[u].

array Adj

Adjacency-list representationIf G is a directed graph, the sum of the lengths of all the adjacency lists is |E|, since and edge of the form (u, v) is represented by having v appear in Adj[u].

If G is undirected graph, the sum of the lengths of all the adjacency lists is 2 |E|, since if (u, v) is an undirected edge, then u appears in v’s adjacency list and vice versa.

For both directed and undirected graphs, the amount of memory required is Θ(V+E).

Adjacency-list representationWeighted graphs are the ones where each edge has an associated weight.

Weight function w : E→R.

We store the weight w(u,v) with vertex v in u’s adjacency list.

Disadvantage of adjacency-list representation:

No quick way to determine whether a given edge (u, v) is present in the graph.

The only way is to search for v in the list Adj[u].

Adjacency-matrix representationFor adjacency-matrix representation of a graph G = (V, E), we assume that the vertices are numbered 1, 2, 3, …, |V| in some arbitrary manner.

Then the adjacency-matrix representation of a graph G consists of a |V| x |V| matrix A = (aij) such that

This representation requires Θ(V2) memory, independent of the number of edges in the graph.

Adjacency-matrix representationFor undirected graphs, the matrix is symmetrical, because (u, v) and (v, u) represent the same edge.

For directed graphs, the matrix is unsymmetrical.

In case of weighted graphs, we can simply store the weight w(u, v) as the entry in row u and column v of the adjacency matrix. If edge does not exist, NIL or 0 or ∞ may be stored.

Adjacency matrix representations are simpler (although space inefficient), so for reasonably small graphs, they are preferred. Also, for unweighted graphs, they require only one bit per entry.

Classwork

Breadth-first searchGiven a graph G = (V, E) and a distinguished source vertex s, breadth-first search systematically explores the edges of G to ‘discover’ every vertex that is reachable from s.It computes the distance (smallest number of edges) from s to each reachable vertex.It also produces a ‘breadth-first tree’ with root s that contains all reachable vertices.In the breadth-first tree, a simple path from s to any vertex v corresponds to a ‘shortest path’ from s to v.It works on both directed and undirected graphs.It is so named because, it discovers all vertices at distance k from s before discovering any vertices at distance k + 1.

Breadth-first search (BFS)To keep track of progress, breadth-first search colors each vertex white, gray, or black.

All vertices start out white (undiscovered), and then may become gray or black (discovered).

BFS distinguishes between gray and black to ensure the search proceeds in a breadth-first manner.

All vertices adjacent to black are either black or gray (i.e. discovered).

Gray vertices may have some adjacent vertices white; they represent the frontier between discovered and undiscovered vertices.

Breadth-first searchBFS constructs a breadth-first tree, initially containing only its root (source vertex s).

Start by scanning the adjacency list of the vertex s. (in an adjacency-list representation)

When a white vertex v is found in the adjacency list, the vertex v and edge (s, v) are added to the tree.

We say that s is a predecessor or parent of v in the breadth-first tree.

Since a vertex is discovered at most once, it can have only one parent (at most).

BFS uses first-in, first-out Queue.

(parent)

Breadth-first search (initialization)

(parent)

Running time of BFSInitialization → O(V)

Each vertex is enqueued at most once and dequeued at most once → O(V)

The algorithm scans the adjacency-list of a vertex only when it is queued, so adjacency-lists are scanned only once. Total sum of all adjacency-lists is E. → O(E)

Total running time → O(V + E).

BFS runs in time linear in the size of the adjacency-list representation of G.

Breadth-first tree and shortest pathsBFS builds a breadth-first tree as it searches the graph. The tree corresponds to the attributes.

Breadth-first tree (a predecessor subgraph) of a graph G = (V, E) is G = (V , E ) so that:

V = {v ∈ V : v. ≠ NIL} U {s}

E = {(v. , v): v ∈ V - {s}}

The subgraph G contains a unique simple path from s to v that is also a shortest path from s to v in G.

Since G is a connected tree, |E | = |V | - 1

ClassworkDraw a Breadth-first tree for Chennai (C)

What is the distance from C to each of the other cities?

V = {v ∈ V : v. ≠ NIL} U {s}

E = {(v. , v): v ∈ V - {s}}

Depth-first searchThe strategy is to search ‘deeper’ in the graph whenever possible.

Unlike BFS, whose predecessor subgraph forms a tree, the predecessor subgraph produced by DFS may be composed of several trees (i.e. a depth-first forest) → because the search may repeat from multiple sources.

Predecessor subgraph of a graph G is G = (V, E ) and E = {(v. , v): v ∈ V and v. ≠ NIL}.

As we search, we also record two timestamps - v.d (records when v is first discovered - grayed) and v.f (when v’s adjacency list is finished examining - blackened).

These timestamps are integers between 1 and 2|V|; and for every vertex u, u.d < u.f.

Depth-first search (DFS)

DFS

DFS

Running time of DFSInitialization takes Θ(V) time.

Every edge (in the adjacency-list) is processed only once and sum of all |Adj[v]| is Θ(E). i.e. DFS-VISIT() needs Θ(E) time.

Total DFS running time = Θ(V + E)

Classification of edgesDFS can be used to classify the edges of the input graph G = (V, E).

Tree edges are edges in the depth-first forest.

A edge (u,v) in G is a back edge if v is ancestor of u in the depth-first forest.

Forward edges are those nontree edges (u,v) connecting a vertex u to a descendant v in the depth-first tree.

Cross edges are all other edges. They can go between vertices in the same tree or between vertices.

Example application: A directed graph is acyclic if and only if a depth-first search yields no ‘back’ edges.

Classwork

Run DFS for the graph below.

Make following assumptions:

(a) Vertices are considered alphabetically (not randomly)

(b) Each adjacency list is sorted alphabetically (not randomly)

1. Show discovery and finish times for each vertex.

2. Show classification of each edge.

Topological sortA topological sort of a directed acyclic graph (DAG) G = (V, E) is a linear ordering of all its vertices such that if G contains an edge (u, v), then u appears before v in the ordering.

In applications that need topological sorting, directed acyclic graphs are used to indicate the precedences among events.

If a graph contains a cycle, no linear ordering is possible. Why?

DFS can be used to perform topological sort.

a DAG showing precedences among events

Topological sortSay, A, B, C, D, E, and F are activities with dependencies shown below.

Which is a topological sort, and which is not?

Topological sort

TOPOLOGICAL-SORT(G) - Identify the vertices that have no incoming edges (say I is the set) - For each vertex in I, call DFS(G) and compute finish times v.f for each vertex - As each vertex’s finish time is computed, insert it onto the front of a linked list - Return the linked list of vertices

Running time is Θ(V + E)

ClassworkShow the ordering of vertices produced by TOPOLOGICAL-SORT() when it is run on the following DAG.

Make following assumptions:

(a) Vertices are considered alphabetically (not randomly)

(b) Each adjacency list is sorted alphabetically (not randomly)

TOPOLOGICAL-SORT(G)- Identify the vertices that have no incoming edges

(say I is the set)- For each vertex in I, call DFS(G) and compute finish

times v.f for each vertex- As each vertex’s finish time is computed, insert it

onto the front of a linked list- Return the linked list of vertices

SummaryGraphs can be represented using adjacency-lists and adjacency matrices. Matrix representation is easy and well-suited for small problems, but adjacency-list representation is more widely used.

Breadth-first search and depth-first search both run in Θ(V + E) time. BFS uses queue and DFS can use stack (although we discussed only using recursion).

BFS and DFS (by default) only operate on unweighted graph.

Topological sort uses DFS for building a topologically sorted graph for a directed acyclic graph.