'

CS 310

$ 1

Graphs

A graph consists of a set of vertices V and a set of edges E = f(v1 ; v2 )jv1 ; v2 2 V g. If (v1 ; v2 ) are ordered, we have a directed graph. A

& C

B

D

E

V = {A,B,C,D,E} E = {(A,C),(A,D),(A,E) (B,E),(C,A),(C,B), (C,D),(D,C),(E,D) }

%

'

$

CS 310

2

If (v1 ; v2 ) are unordered, we have a undirected graph. A

C

&

B

D

E

V = {A,B,C,D,E} E = {(A,C),(A,D),(A,E) (B,C),(B,E),(C,A),(C,B), (C,D),(D,C),(D,A),(D,E), (E,A),(E,B),(E,D)}

%

'

CS 310

$ 3

Terminology

Vertices vi and vj are adjacent if either (vi ; vj ) 2 E or (vj ; vi ) 2 E . A path in a graph is a sequence of vertices v1 ; v2 ; : : : ; vn where all (vi ; vi+1) 2 E ; 8i = 1; : : : ; n , 1. The length of this path is n , 1. A

C

&

Some paths:  A,D,C,B  A,D,C,A

B

D

E

V = {A,B,C,D,E} E = {(A,C),(A,D),(A,E) (B,E),(C,A),(C,B), (C,D),(D,C),(E,D) }

 A,C,A,E,D,C,A

%

CS 310

' More Terminology

 Simple path { All vertices are distinct except possibly the v1 and vn . >

v

vn

 Cycle { path of length = 1 where 1 = .

 Weighted graph { a graph with \costs" associated with each edge.

 Connected Components { A directed graph is strongly connected if there is a directed path from every vertex to every other vertex. A directed graph is weakly connected if for every pair of vertices V1 and V2 , there is either a path P(V1 ,V2 ) or P(V2 ,V1 ).

&

4

$

%

'

CS 310

$ 5

Directed Acyclic Graph (DAG)

A directed graph containing no cycles A

C

&

B

D

E

V = {A,B,C,D,E} E = {(A,C),(A,D),(A,E) (B,E),(C,B),(C,D), (E,D)}

A tree is also an example of a directed acyclic graph.

%

CS 310

InsertEdge:

! Graph

Graph ADT ! Graph

(Graph,vertex)

(Graph,vertex1 ,vertex2 )

! Graph

Action: Add a new vertex to the graph. Pre: vertex should not already be in the graph.

InsertVertex:

Action: create a new graph

Constructor:

'   

Action: Add an edge to the graph. Pre: vertex1 and vertex2 must already be in the graph.

&

6

$

%

CS 310 DeleteVertex:

(Graph,vertex)

! Graph

(Graph,vertex1 , vertex2 )

GetNeighbors:

(Graph,vertex)

!

! Graph

is an edge

Action: Remove the edge (vertex1 , vertex2 ) from the graph. Pre: Call to InsertEdge(vertex1 ,vertex2 ) should have occurred previously.

DeleteEdge:

Action: Remove vertex from the graph. Also remove any edges of the form (vertex1 , vertex2 ), where either vertex1 or vertex2 is vertex. Pre: Call to InsertVertex(vertex) should have occurred previously.

' 





vertex list vertex1 )

Action: Find all vertex1 where (vertex, in the graph. Pre: vertex must be in the graph.

&

7

$

%

CS 310

' Traversing a Graph: DFS

Depth First Search (DFS) main() f for (v is node in graph) if (v has not been visited) dfs(v);

g

dfs(vertex v) mark v as having been visited list = neighbors of v while there is an unvisited neighbor w of v dfs(w)

&

8

$

%

'

$

CS 310

9

A

DF tree arcs

A

Cross arcs Back arcs B

B

D

C C

&

E

Forward arcs

D

F

E

F

%

$

dfs(A) dfs(B) dfs(C) B already visited dfs(D) C already visited dfs(E) C already visited dfs(F) C already visited D already visited

10

'

%

CS 310

&

CS 310

' Breadth First

Queue q; main() f initialize all nodes { visited = false, queued = false for (v is node in graph) if (v has not been visited) bfs(v);

g

bfs(vertex v) q.enqueue(v) while not q.empty() do w = q.dequeue() mark w as having been visited for all neighbors x with queued = false, queued = true for x q.enqueue(x)

&

11

$

%

'

$

CS 310

12

A

DF tree arcs

A

Cross arcs Back arcs B

B

D

C C

&

E

Forward arcs

D

F

E

F

%

'

$

CS 310

1

Representation of Graphs A

C

D

E

V = {A,B,C,D,E} E = {(A,C),(A,D),(A,E) (B,E),(C,A),(C,B), (C,D),(D,C),(E,D) }

A B 2 Adjacency matrix { Space O(jV j ) C D E

& 

B

A 0 0 1 0 0

B 0 0 0 1 0

C 1 0 0 1 0

D 1 0 1 0 1

E 1 1 0 0 0

%

'

$

CS 310



2

Adjacency list

A=0

2

B=1

4

C=2 D=3

& E=4

0 1

3

3

4

3 2

%

Adjacency table template class Digraph { int count; // number of vertices, at most max_size bool adjacency[max_size][max_size]; }

Adjacency Lists typedef int Vertex; template class Digraph { int count; List neighbors[max_size]; };

Adjacency Lists class Edge; class Vertex { Edge *first_edge; Vertex *next_vertex; } class Edge { Vertex *end_point; Edge *next_edge; }; class Digraph { Vertex *first_vertex; };

cont’d

// forward declaration // start of adjacency list // next vertex on linked list of vertices

// vertex to which the edge points // next edge on adjacency list

// header for list of vertices

'

CS 310

$ 8

Topological sorting on DAGS

Suppose we have 10 tasks and a graph represents a partial order on these tasks where Ti ! Tj means that task Ti must be complete before task Tj can start.

1

2

5

7

3

6

8

4

10

9

What order should the tasks be done? Some possibilities: 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ! 8 ! 9 ! 10 1 ! 3 ! 4 ! 6 ! 2 ! 5 ! 7 ! 9 ! 8 ! 10 1 ! 4 ! 3 ! 2 ! 6 ! 5 ! 9 ! 8 ! 7 ! 10

&

%

Topological sort • Depth-first – find node with no successor and place it last in order – use depth-first traversal

• Breadth-first – find node with no predecessor and place it first in order – use breadth-first traversal

typedef int Vertex; template class Digraph { public: Digraph(); void read(); void write(); void depth_sort(List &topological_order); void breadth_sort(List &topological_order); private: int count; List neighbors[graph_size]; void recursive_depth_sort(Vertex v, bool visited[], List &topological_order); };

template void Digraph::depth_sort(List &topological_order) /*Post: The vertices of the Digraph are placed into List topological_order with a depth-first traversal of those vertices that do not belong to a cycle. Uses: Methods of class List, and function recursive_depth_sort to perform depth-first traversal.*/ { bool visited[graph_size]; Vertex v; for (v = 0; v < count; v++) visited[v] = false; topological_order.clear(); for (v = 0; v < count; v++) if (!visited[v]) // Add v and its successors into topological order. recursive_depth_sort(v, visited, topological_order); }

template void Digraph::recursive_depth_sort(Vertex v, bool *visited, List &topological_order) { visited[v] = true; int degree = neighbors[v].size(); for (int i = 0; i < degree; i++) { Vertex w;

// A (neighboring) successor of v

neighbors[v].retrieve(i, w); if (!visited[w])

// Order the successors of w.

recursive_depth_sort(w, visited, topological_order); } topological_order.insert(0, v); // Put v into topological_order. }

CS 310

' Topological Sort

1. 8 vertices v, compute predv , the number of tasks that vertex depends on (directly). 8

vertices x where w ! x, decrement predx

2. Find a vertex w where predw = 0. Output w. 3.

4. repeat steps 2 and 3 until either:

(a) No more vertices in the graph | SUCCESS (b) More tasks but none with predv = 0 | FAILURE { we did not start with a DAG

&

9

$

%

template void Digraph::breadth_sort(List &topological_order) { topological_order.clear(); Vertex v, w; int predecessor_count[graph_size]; for (v = 0; v < count; v++) predecessor_count[v] = 0; for (v = 0; v < count; v++) for (int i = 0; i < neighbors[v].size(); i++) { // Loop over all edges v -- w. neighbors[v].retrieve(i, w); predecessor_count[w]++; }

Queue ready_to_process; for (v = 0; v < count; v++) if (predecessor_count[v] == 0) ready_to_process.append(v); while (!ready_to_process.empty( )) { ready_to_process.retrieve(v); topological_order.insert(topological_order.size(), v); for (int j = 0; j < neighbors[v].size(); j++) { // Traverse successors of v. neighbors[v].retrieve(j, w); predecessor_count[w]--; if (predecessor_count[w] == 0) ready_to_process.append(w); } ready_to_process.serve(); } }

CS 310

' Spanning Trees

If the graph is undirected, DFS and BFS are good ways to see if the graph is connected (i.e. possible path between all nodes). These traversals de ne spanning trees.

&

13

$

%

'

$

CS 310

14

Spanning Trees

Initial Graph A

B

D

C

E

Spanning Trees A

C

&

A

B

D

C

E

A

C

D

B

D

B

E

E

%

'

$

CS 310

15

Weighted Graphs A graph consists of a set of vertices V , a set of edges E = f(v1 ; v2 )jv1 ; v2 2 V g, and a weighting function: E ! I. A 28 B

15

20

&

24

C

D

12 E

11 13

F

A

C 28

D 24

B

C 14

E 20

C

A 28

B 15

D

A 24

F 11

B 20

C 12

D 11

E 13

E F

E 12

F 13

%

CS 310

'

Minimum Spanning Trees { Kruskal's

 Greedy  Idea: consider the lightest edges rst Algorithm:

1. First, we need to view the graph of n nodes as n separate components.

2. Consider the edges in increasing order of their weights.

3. If an edge has ends in 2 di erent components, select that edge for the spanning tree and merge the components. Otherwise, the edge will not be part of the MST

&

16

$

%

'

$

CS 310

17

A 28

B

13

14

A 24

C

28

D

11

12 16

E

13

B

C

D

11

14

F

B

13

14

&

28

D

11 E

13

B

12 16

E

A

13

14

24

C

D

11 E

12 16

D

11

14

28

24

C

F

B

F

A 24

C

12 16

E

A 28

24

F

12 16

F

%

CS 310

Dijkstra's Algorithm { Single source, all destinations

' 

Assumes no negative edges

Shortest Paths { Weighted Graphs



&

3

$

%

'

$

CS 310

4

A 4 4

B 2

6

8

&

C

9

3

D 5

E 5

7 F

%

'

$

CS 310

5

Graph G

&

%

CS 310

' Algorithm

1. Initialize: settled = f initial g i, distance(i) = 1, successor(i) = NULL 8

2. 8 nodes j : 2 settled, compute distance(j ) = min(distance(j ),distance(i)+cost(i,j ) where i ! j and i 2 settled).

3. Choose i ! k where i 2 settled, k: 2 settled, and k has the smallest of the distance(k) computed in the previous step.  settled = settled [ f k g  successor(k) = i 4. if settled 6= V goto step 2

&

6

$

%

CS 310

'

& Initially

A

A

A

4

4

9

4

B 4

B

6

8 2

6

8

5

3

C

7

E

C

F

4

2 6

8 C

3

5 E

C

5

3

E 5

5

Distance(B) = 4 Distance(D) = 8 Distance(C) = 12

D

7 F

4

E

F

Distance(B) = 4 Distance(D) = 8 Distance(C) = 12 Distance(E) = 13

F

6

8

7 C

9 4

B 2

6

8

7

Distance(B) = 4 Distance(D) = 8

9 4

B

D

5

A

4

9

D

5

A

4

3

C

F

Distance(B) = 4

A

2

E

6

8

7

5

5

B

3

5

9 4

B

D 2

2

D

4

9

3

D 5

E

7 F

5

Distance(B) = 4 Distance(D) = 8 Distance(C) = 12 Distance(E) = 13 Distance(F) = 17

7

$

%