550 likes | 701 Views
B. F. G. A. C. D. E. Graphs. Graph G(V,E): finite set V of nodes (vertices) plus a finite set E of arcs (or edges) between nodes V = {A, B, C, D, E, F, G} E = {AA, AB, AD, CD, DE, BF, EF, FG, EG }. Terminology. Two vertices are adjacent if they are connected with an edge
E N D
B F G A C D E Graphs • Graph G(V,E): finite set V of nodes (vertices) plus a finite set E of arcs (or edges) between nodes • V = {A, B, C, D, E, F, G} • E = {AA, AB, AD, CD, DE, BF, EF, FG, EG } Graphs
Terminology • Two vertices are adjacent if they are connected with an edge • Adjacent or neighbor vertices • Subgraph of G=(V,E): a graph G’=(V’,E’) where V’, E’ are subsets of V, E • |V|,|E|: number of nodes, edges of G • Complete graph: contains all possible edges • |E| in Θ(|V|2) Graphs
B C A G E D H F Undirected Graphs • The edges are not directed from one vertex to another Graphs
B C A G E D H F Directed Graphs • The edges are directed from one vertex to another Graphs
A A B C B C D D E F G Graphs
More Definitions • Vertex degree: maximum number of incoming or outgoing edges • in-degree: number of incoming edges • out-degree: number outgoing edges • RelationRonA: R = {<x, y>| x, y ∊ N} • x < y • x mod y = odd • Labeled graph: labels on vertices or edges • Weighted graph: weights on edges Graphs
1 relation weighted 3 10 3 10 7 3 1 5 8 5 8 17 17 1 5 6 6 Graphs
Paths • There exist edges connecting two nodes • Length of path: number of edges • Weighted graphs: sum of weights on path • Cycle: path (of length 3 or more) connecting a vertex with itself • Cyclic graph: contains cycle • Acyclic graph: does not contain cycle • DAG:Directed Acyclic Graph Graphs
7 2 6 0 4 3 5 1 Connected Graphs • An undirected graph is connected if there is a path between any two vertices • Connected components: maximally connected subgraphs Graphs
a b a b a b a b a b a b a b c Operations on Graphs • join (a,b) • join (a,b,x) • remv[wt] (a,b,x) • adjacent (a,b) x adjacent (a,b) = true adjacent (a,c) = false Graphs
Build a Graph read(n); // number of nodes read and create n nodes label them from 1 .. n while not eof(..) { read(node1, node2, w12); joinwt(node1, node2, w12); } any graph algorithm Graphs
directed graph 0 1 2 3 4 0 2 0 1 1 1 1 4 2 1 1 3 3 1 4 1 adjacency matrix 0 1 4 1 3 2 4 3 adjacency list 2 4 1 Representation of Directed Graphs Graphs
undirected graph 0 1 2 3 4 0 1 1 0 2 1 1 1 1 2 1 1 4 3 1 1 1 4 1 1 1 3 0 1 4 1 0 3 4 2 3 4 3 1 2 adjacency list 4 0 1 2 Representation of Undirected Graphs adjacency matrix Graphs
Matrix Implementation • Simple but difficult to process edges, unused space in matrix • mark: 1D array marking vertices • mark[i] = 1 if vertex i has been visited • typedef int *Edge; • matrix: the actual Graph implemented as an 1D array of size n2 • edge (i, j) is found at matrix[i*n + j] • if edge exists matrix[i*n + j] = wt • otherwise matrix[i*n + j] = NOEDGE Graphs
Graph Interface interface Graph { // Graph class ADT public int n(); // Number of vertices public int e(); // Number of edges public Edge first(int v); // Get first edge for vertex public Edge next(Edge w); // Get next edge for a vertex public boolean isEdge(Edge w); // True if this is an edge public boolean isEdge(int i, int j); // True if this is an edge public int v1(Edge w); // Where edge came from public int v2(Edge w); // Where edge goes to public void setEdge(int i, int j, int weight); // Set edge weight public void setEdge(Edge w, int weight); // Set edge weight public void delEdge(Edge w); // Delete edge w public void delEdge(int i, int j); // Delete edge (i, j) public int weight(int i, int j); // Return weight of edge public int weight(Edge w); // Return weight of edge public void setMark(int v, int val); // Set Mark for v public int getMark(int v); // Get Mark for v } // interface Graph Graphs
Implementation: Edge Class interface Edge { // Interface for graph edges public int v1(); // Return the vertex it comes from public int v2(); // Return the vertex it goes to } // interface Edge // Edge class for Adjacency Matrix graph representation class Edgem implements Edge { private int vert1, vert2; // The vertex indices public Edgem(int vt1, int vt2) { vert1 = vt1; vert2 = vt2; } public int v1() { return vert1; } public int v2() { return vert2; } } // class Edgem Graphs
Graph class: Adjacency Matrix class Graphm implements Graph { // Graph: Adjacency matrix private int[][] matrix; // The edge matrix private int numEdge; // Number of edges public int[] Mark; // The mark array public Graphm(int n) { // Constructor Mark = new int[n]; matrix = new int[n][n]; numEdge = 0; } public int n() { return Mark.length; } // Number of vertices public int e() { return numEdge; } // Number of edges Graphs
Adjacency Matrix (cont.) public Edge first(int v) { // Get the first edge for a vertex for (int i=0; i<Mark.length; i++) if (matrix[v][i] != 0) return new Edgem(v, i); return null; // No edge for this vertex } public Edge next(Edge w) { // Get next edge for a vertex if (w == null) return null; for (int i=w.v2()+1; i<Mark.length; i++) if (matrix[w.v1()][i] != 0) return new Edgem(w.v1(), i); return null; // No next edge; } Graphs
Adjacency Matrix (cont.) public boolean isEdge(Edge w) { // True if this is an edge if (w == null) return false; else return matrix[w.v1()][w.v2()] != 0; } public boolean isEdge(int i, int j) // True if this is an edge { return matrix[i][j] != 0; } public int v1(Edge w) // Where edge comes from { return w.v1(); } public int v2(Edge w) // Where edge goes to { return w.v2(); } Graphs
Adjacency Matrix (cont.) // Set edge weight public void setEdge(int i, int j, int wt) { Assert.notFalse(wt!=0, "Cannot set weight to 0"); matrix[i][j] = wt; numEdge++; } // Set edge weight public void setEdge(Edge w, int weight) { if (w != null) setEdge(w.v1(), w.v2(), weight); } Graphs
Adjacency Matrix (cont.) public void delEdge(Edge w) { // Delete edge w if (w != null) if (matrix[w.v1()][w.v2()] != 0) { matrix[w.v1()][w.v2()] = 0; numEdge--; } } public void delEdge(int i, int j) { // Delete edge (i, j) if (matrix[i][j] != 0) { matrix[i][j] = 0; numEdge--; } } Graphs
Adjacency Matrix (cont.) public int weight(int i, int j) { // Return weight of edge if (matrix[i][j] == 0) return Integer.MAX_VALUE; else return matrix[i][j]; } public int weight(Edge w) { // Return weight of edge Assert.notNull(w, "Can't take weight of null edge"); if (matrix[w.v1()][w.v2()] == 0) return Integer.MAX_VALUE; else return matrix[w.v1()][w.v2()]; } public void setMark(int v, int val) { Mark[v] = val; } // Set Mark public int getMark(int v) { return Mark[v]; } // Get Mark } // class Graphm Graphs
Implementation: Edge Class // Edge class for Adjacency List graph representation class Edgel implements Edge { private int vert1, vert2; // Indices of v1, v2 private Link itself; // Pointer to node in adj list public Edgel(int vt1, int vt2, Link it) //Constructor { vert1 = vt1; vert2 = vt2; itself = it; } public int v1() { return vert1; } public int v2() { return vert2; } Link theLink() { return itself; } // Access adj list } // class Edgel Graphs
Graph Class: Adjacency List class Graphl implements Graph { // Graph: Adjacency list private GraphList[] vertex; // The vertex list private int numEdge; // Number of edges public int[] Mark; // The mark array public Graphl(int n) { // Constructor Mark = new int[n]; vertex = new GraphList[n]; for (int i=0; i<n; i++) vertex[i] = new GraphList(); numEdge = 0; } Graphs
Adjacency List (cont.) public int n() { return Mark.length; } // Number of vertices public int e() { return numEdge; } // Number of edges public Edge first(int v) { // Get the first edge for a vertex vertex[v].setFirst(); if (vertex[v].currValue() == null) return null; return new Edgel(v, ((int[])vertex[v].currValue())[0], vertex[v].currLink()); } Graphs
Adjacency List (cont.) public boolean isEdge(Edge e) { // True if this is an edge if (e == null) return false; vertex[e.v1()].setCurr(((Edgel)e).theLink()); if (!vertex[e.v1()].isInList()) return false; return ((int[])vertex[e.v1()].currValue())[0] == e.v2(); } public boolean isEdge(int i, int j) { // True if this is an edge GraphList temp = vertex[i]; for (temp.setFirst(); ((temp.currValue() != null) && (((int[])temp.currValue())[0] < j)); temp.next()); return (temp.currValue() != null) && (((int[])temp.currValue())[0] == j); } 110,60 Graphs
Adjacency List (cont.) public int v1(Edge e) { return e.v1(); } // Where edge comes from public int v2(Edge e) { return e.v2(); } // Where edge goes to public Edge next(Edge e) { // Get next edge for a vertex vertex[e.v1()].setCurr(((Edgel)e).theLink()); vertex[e.v1()].next(); if (vertex[e.v1()].currValue() == null) return null; return new Edgel(e.v1(), ((int[])vertex[e.v1()].currValue())[0], vertex[e.v1()].currLink()); } 110,60 Graphs
Adjacency List (cont.) public void setEdge(int i, int j, int weight) {// Set edge weight Assert.notFalse(weight!=0, "Cannot set weight to 0"); int[] currEdge = { j, weight }; if (isEdge(i, j)) // Edge already exists in graph vertex[i].setValue(currEdge); else { // Add new edge to graph vertex[i].insert(currEdge); numEdge++; } } public void setEdge(Edge w, int weight) // Set edge weight { if (w != null) setEdge(w.v1(), w.v2(), weight); } Graphs
Adjacency List (cont.) public int weight(int i, int j) { // Return weight of edge if (isEdge(i, j)) return ((int[])vertex[i].currValue())[1]; else return Integer.MAX_VALUE; } public int weight(Edge e) { // Return weight of edge if (isEdge(e)) return ((int[])vertex[e.v1()].currValue())[1]; else return Integer.MAX_VALUE; } public void setMark(int v, int val) { Mark[v] = val; } // Set Mark public int getMark(int v) { return Mark[v]; } // Get Mark } // class Graphl Graphs
ndptr nextarc arcptr info nextnode info: data arcptr: pointer to an adjacent node nextnode: pointer to a graph node ndptr: pointer to adjacent node nextarc: pointer to next edge B A D C E A Better Implementation Graphs
graph C D n i l E n i l n i l n i l Β A <D,B> n i l <C,E> n i l <A,B> <A,C> <A,D> <A,E> Graphs
Graph Traversal • Trees • preorder • inorder • postorder • Graphs • Depth First Search (DFS) • Breadth First Search (BFS) Graphs
Depth First Search (DFS) • Starting from vertex v, initially all vertices are “unvisited” • void DFS(v) { Mark(v) = true; for each vertex w adjacent to v if (!Mark(w)) DFS(w) } Graphs
Complexity of DFS • O(|V| + |E|): adjacency list representation • O(|V|2) in dense graphs • O(|V|2):matrix representation Graphs
v = v1 7 v3 v2 v1 v6 v5 v4 v8 v7 1 1 7 5 6 8 2 2 5 3 3 4 2 4 6 8 8 8 3 DFS : V1V2V4V8V5V6V3V7 v1 v2 v3 v7 v4 v5 v6 v8 Graphs
v = v1 ΒFS : V1V2V3V4V5V6V7V8 v1 v2 v3 v7 v4 v5 v6 v8 Breadth-First Search (BFS) Graphs
BFS (cont.) • Starting from vertex v, all nodes “unvisited”, visit adjacent nodes (use a queue) void DFS(v) { visited(v) = true; enqueue(v, Q); while ( Q ≠ 0 ) { x = dequeue(Q); for each y adjacent x do if ! Mark(y) { Mark(y) = TRUE; enqueue(y,Q); } } } Graphs
front rear output(v1) v2 v3 v1 v5 v4 v8 v4 v7 v8 v7 v5 v6 v5 v8 v6 v7 v6 v6 v3 v1 front v2 v3 output(v2) rear v7 v4 v5 v6 output(v3) front front v8 front output(v4) rear rear rear front output(v5) output(v6) front output(v7) v = v1 Graphs
Complexity of BFS • O(|V|+|E|) : adjacency list representation • d1 + d2 + ...+ dn = |E| • di= degree (vi) • O(|V|2) : adjacency matrix representation Graphs
DFS Algorithm static void DFS (Graph G, int v){ PreVisit(G, v); // Take appropriate action G.setMark(v, VISITED); for ( Edge w = G.first(v); G.isEdge(w); w = G.next(w)) if (G.getMark(G.v2(w)) = = UNVISITED) DFS ( G, G.v2(w)); PostVisit(G, v); // Take appropriate action } Graphs
BFS Algorithm void BFS (Graph G, int start){ Queue Q(G.n( )); Q.enqueue(start); G.setMark(start, VISITED); while ( !Q.isEmpty( )) { int v = Q.dequeue( ); PreVisit(G, v); // Take appropriate action for ( Edge w = G.first(v); G.isEdge(w); w = G.next(w)) if (G.getMark(G.v2(w)) = = UNVISITED){ G.setMark(G.v2(w), VISITED);Q.enqueue(G.v2(w)); } PostVisit(G, v); // Take appropriate action } } Graphs
B C A D E F A E B G C D connected components Connected - Unconnected connected graph: undirected graph, there is a path connecting any two nodes unconnected graph: not always a path Graphs
Connected Components • If there exist unconnected nodes in a DFS or BFS traversal of G then G is unconnected • Find all connected components: void COMP(G, n) { for i = 1 to n if Mark(i) == UNVISITED then DFS(i) [or BFS(i)]; } • Complexity: O(|V| + |E|) Graphs
(G,E) Spanning Trees Tree formed from edges and nodes of G Spanning Tree Graphs
Spanning Forest • Set of disjoint spanning trees Tiof G=(V,E) • Ti = ( Vi , Ei ) 1≤ i ≤ k, Vi,Ei:subsets of V, E • DFS producesdepth first spanning trees or forest • BFS breadth first spanning trees or forest • Undirected graphs provide more traversals • produce less but short spanning trees • Directed graphs provide less traversals • produce more and higher spanning trees Graphs
DFS spanning tree A A B B C C D E A DFS A D E B F DFS spanning forest DFS B C C E F D D E G G DFS Graphs
A ΒFS A B F B C E C F D D E H H BFS A A BFS spanning tree ΒFS B C D B C D E F G E F G BFS spanning forest Graphs
1 Prim’s algorithm: Complexity O(|V|2) 6 5 1 5 5 2 3 4 6 4 2 3 5 6 6 1 1 1 1 1 1 1 1 1 1 5 5 3 3 3 4 2 3 4 2 3 4 4 4 2 4 2 4 2 3 6 6 6 5 6 costT = 1 + 5 + 2 + 4 + 3 Min. Cost Spanning Tree Graphs
Prim’s Algorithm static void Prim(Graph G, int s, int[] D ) {//prim’s MST algorithm int[] V = new int[G.n( )]; // who’s closest for (int i=0; i<G.n( ); i++) D[i] = INFINITY; // initialize D[s] = 0; for ( i=0; i<G.n( ); i++) { // process the vertices int v = minVertex(G, D); G.setMark(v], VISITED); if ( v != s ) AddEdgetoMST(V[v], v); // add this edge to MST if (D[v] == INFINITY ) return; // unreachable vertices for ( Edge w = G.first(v); G.isEdge(w); w = G.next(w)) if (D[G.v2(w)] > G.weight(w)) { D[G.v2(w)] = G.weight(w); // update distance and V[G.v2(w)] = v; // who it came from } } } Graphs
Prim’s Algorithm (cont.) // find min cost vertex static int minVertex(Graph G, int[] D ){ int v = 0; for (int i = 0; i < G.n( ); i++) // initialize if (G.getMark(i) == UNVISITED) { v = i; break; } for ( i=0; i<G.n( ); i++) // find smallest value if ((G.getMark(i) == UNVISITED) && ( D[i] < D[v] )) v = i; return v; } Graphs