670 likes | 696 Views
Explore the Konigsberg bridge problem, a graph theory problem that asks whether it is possible to walk across all bridges in a land area once and return to the initial land area. Understand the definitions of graphs, paths, cycles, connectivity, and explore examples and solutions.
E N D
Motivating Problem • Konigsberg bridge problem (1736): Starting in one land area, is it possible to walk across all bridges once and return to the initial land area? C d c g A D e a b f The answer is no, but how do we prove that? B
Konigsberg = Graph Problem • The Konigsberg is an instance of a graph problem • Definition of a graph: • Graph G: Consists of two sets, V and E • V: A finite, non-empty set of vertices • E: A set of pairs of vertices, where the pairs are called edges.
Example Graphs V: 0, 1, 2, 3 E: (0,1), (0,2), (0,3) (1,2), (1,3), (2,3) V: 0, 1, 2, 3 E: Empty 0 0 1 2 3 1 2 0 3 V: 0, 1, 2, 3 E: (0,1), (0,2), (1,3) Trees are a subset of graphs 1 2 3
Graph Definitions • Undirected graph: Pair of vertices representing any edge is unordered • (u,v) is the same edge as (v,u) • Directed graph: Each edge is represented by a directed pair (u,v) • Drawn with an arrow from u to v indicating the direction of the edge • (u,v) is not the same edge as (v,u)
Directed vs. Undirected 0 0 0 1 2 1 2 1 2 3 3 3 Graph C: Directed Equivalent to A (1,0) is a valid edge A (0,1) edge also exists Graph A: Undirected (1,0) is a valid edge Same as (0,1) edge Graph B: Directed Not equivalent to A (1,0) not valid edge
Graph Restrictions • For now lets assume vertices and edges are sets • No self edges (vertice back to itself) • No repeated edges (multigraph) 0 Self 1 2 Repeated 3
Motivating Problem: Graph Restrictions • Konigsberg bridge problem (1736): This is the appropriate graph representation. We’re not going to solve it for now because of our assumption of no repeated edges. 0 1 3 2
Graph Definitions • Maximum possible number of distinct unordered pairs (u,v) (undirected graph) in a graph with n vertices is n*(n-1) / 2. • A graph with this many edges is called a complete graph. 0 0 Complete: 6 edges = (4 * 3) / 2 1 2 1 2 Not Complete: (4*3)/2 != 4 edges 3 3
Graph Definitions • Directed Graph: • Maximum of (n * (n-1)) edges. [Twice that for undirected because 2 directed are equivalent to one undirected] Proof of (n * (n – 1)) bounds: n nodes, can point to every other node except for themselves n-1 edges connecting to each of the n nodes
Graph Definitions • If (u, v) is an edge in E(G), • Vertices u and v are called adjacent • The edge (u,v) is called incident on vertices u and v. • Examples: Vertex 0 is adjacent to 1 and 2 Vertex 1 is adjacent to 0, 2, and 3 Vertex 2 is adjacent to 0 and 1 Vertex 3 is adjacent to 1 Edges incident on vertex 2: (0,2), (1,2) Edges incident on vertex 3: (1,3) 0 1 2 3
Graph Definitions • A subgraph of graph G called G’ is a graph such that V(G’) is a subset V(G) and E(G’) is a subset of E(G) Subgraphs 0 1 0 1 2 1 2 3 0 3 1 2
Graph Definitions • A path from vertex u to vertex v in a graph G is a sequence of vertices u, i1, i2, …, ik, v, such that (u,i1), (i1,i2)…(ik,v) are edges in G. • If in a directed graph, the edges have to be in the right direction. • The length of a path is the number of edges on the path. • A simple path is a path in which all vertices except possibly the first and last are distinct.
Graph Definitions Paths from 1 to 3: (1,3) 1,3 [Simple] Length = 1 (1,2), (2,3) 1,2,3 [Simple] Length = 2 (1,0),(0,2),(2,1),(1,3) 1,0,2,1,3 Length = 4 (1,2),(2,0),(0,1),(1,3) 1,2,0,1,3 Length = 4 (1,0),(0,2),(2,3) 1,0,2,3 [Simple] Length = 3 Many more that repeat internally, Not simple, Length > 4 0 1 2 3
Graph Definitions • A cycle is a simple path where the first and last vertices are the same. 0 Cycles to 1: 1,0,2,3,1 1,0,2,1 1,3,2,1 1,2,1 1,0,1 1,3,1 1 2 3
Graph Definitions • Two vertices u and v are connected if there is a path in G from u to v. • An undirected graph is said to be connected (at the graph level) if and only if for every pair of distinct vertices u and v in V(G) there is a path from u to v in G. • A connected component of a graph is a maximal connected subgraph
Graph Definitions 0 4 1 2 5 6 3 7 Graph G4: V(G4): 0,1,2,3,4,5,6,7 E(G4): (0,1), (0,2), (1,3), (2,3), (4,5), (5,6), (6,7) There are two connected components of G4: H1 (0-3) and H2 (4-7) Verify that H1 and H2 components are connected: Path between all pairs of vertices Directed graphs – different because paths are directed, harder to get connected components
Graph Definitions • A tree is a connected, acyclic graph • For any node there is path to any other node (usually back through a “parent node”) • Acyclic property forces a unique path between nodes 0 1 4 2 3
Graph Definitions • Need a corollary to “connected” for directed graphs • A directed graph G is strongly connected if for every pair of distinct vertices in V(G), u and v, there is a directed path from u to v and from v to u. • A strongly connected component is a maximal subgraph of a directed graph that is strongly connected
Graph Definitions 0 1 2 Graph G5: V(G5): 0,1,2 E(G5): (0,1), (1,0), (1,2) G5 is not strongly connected (No path from 2 to 1) There are two strongly connected components of G4: H1 (0-1) and H2 (2) Verify that H1 and H2 components are strongly connected: Directed path between all pairs of vertices
Graph Definitions • The degree of a vertex v is the number of edges incident to that vertex. • For a directed graph, • The in-degree of a vertex v is the number of edges for which the arrow points at v. • The out-degree is defined as the number of edges for which the arrow points away from v.
Graph Definitions 0 Degree of Vertices: 0, 3 => Degree 2 1, 2 => Degree 3 1 2 3 0 0 Out-Degree : 1 In-Degree: 0 1 Out-Degree : 1 In-Degree: 0 2 Out-Degree : 0 In-Degree: 2 1 2
Graph Definitions • For undirected graph whose vertices v_i have degree d_i, the number of edges, |E|, is (the sum from 0 to n-1 of degree_i ) / 2 • Essentially just counting the edges. • Divide by 2 because double counting (if node1, node2 share an edge, that edge is in both of their degrees) • Useful for computing max number of edges if you only know number of vertices and their degree (ie they are all binary => |E| = 2 * |V| / 2 = |V|) • Given our graph assumptions (no repeated edges, no self edges) degree has to be <= |V|-1
Graph Definitions 0 Degree of Vertices: 0, 3 => Degree 2 1, 2 => Degree 3 |E| = Sum of Degrees / 2 = (2+2+3+3)/2 = 10/2 = 5 {Correct!} 1 2 3 0 |E| max = Sum of Degrees / 2 = (2 + 2 + 2) / 2 = 6/2 = 3 {Correct!} |E| Max = ?, All Binary 1 2
Graph Representations • What core functionality do we need in representation? • Set of vertices • Set of edges • Two major representations: • Adjacency matrix [Array based] • Adjacency list [Linked List based]
Adjacency Matrix • G = (V,E) graph with |V| = n, n >= 1 • Adjacency matrix: • 2 dimensional n x n array called A with property that A[i][j] = 1 if the edge (i,j) is in E, 0 otherwise. 0 1 2 3
Adjacency Matrix • Directed Graphs: Rows are the out indicators (data in a row indicates that there is an outgoing link) 0 1 2 3
Adjacency Matrix • Note how the adjacency matrix for an undirected graph is symmetric. Can save approximately half the space by storing only upper triangle or lower triangle 0 1 2 3
Adjacency Matrix Given a complete adjacency matrix, can easily: Determine if there is an edge between any two vertices (look in appropriate column) [Undirected Graph] Compute degree of a node (sum over row) 0 1 2 3
Adjacency Matrix Given a complete adjacency matrix, can easily: [Directed Graph] Compute out degree of a node (sum over row) Compute in degree of a node (sum over column) 0 1 2 3
Adjacency Matrix • What if we want to compute a non-trivial answer? • How many total edges are there in the graph? • Is the graph connected? • Total edges: Requires O(n^2) operations • (n^2 entries – n [diagonals always 0]) 0 1 2 3
Adjacency Matrix • What if we have a sparse graph? • Sparse = Very few connections out of all possible 4 0 5 6 1 2 7 3
Adjacency Matrix • Would really like to do O(|E|) operations when counting edges • O(n^2) is a given when using adjacency matrix • For dense graphs, |E| is close to n^2 • Not for sparse graphs (|E| << n^2) • Solution: Use linked lists and store only those edges that are really represented in the graph (no 0’s for things that aren’t present). • Slightly more complicated to implement but saves a lot of time
Adjacency List • N rows of adjacency matrix (vertices) are represented as n linked lists. • Nodes in list i are those nodes adjacent to the corresponding vertex v_i. Array of Head Node Pointers 0 0 1 2 1 3 0 1 2 2 0 3 3 1 2 3 Order in linked list doesn’t matter
Adjacency List • Undirected Graph: n vertices, e edges – Requires n head nodes, 2 * e list nodes • For any vertex, computing degree (number of incident edges) is counting size of corresponding list. • Number of edges for whole graph is computed in O(n + e) << O(n^2)
Adjacency List for Directed Graph • N rows of adjacency matrix (vertices) are represented as n linked lists. • Nodes in list i are those nodes that one can reach from leaving the corresponding vertex Array of Head Node Pointers 0 0 2 1 2 1 3 0 2 3 3 2 Order in linked list doesn’t matter
Adjacency List • For a directed graph, nodes in a list are those that you can reach leaving from the corresponding vertex • Computing out degree for any vertex – Count number of nodes in corresponding list • Computing number of total edges in graph: Adding all outdegrees => O(n + e) [visit all head nodes and all items in lists] << O(n^2)
Adjacency List • For directed graphs, this approach isn’t very useful for determining in-degree • This was trivial in an adjacency matrix (sum down a column) • You can build the inverse adjacency list at the same time building adjacency list. Array of Head Node Pointers 0 0 1 1 2 1 2 0 3 3 3 1
Primitive Graph Operations • In essence, can just think of a graph as a container, holding edges and vertices (with a lot of special properties): class Graph { public: Graph(); // create an empty graph void InsertVertex(Vertex v); // Insert v into graph with no incident edges void InsertEdge(Vertex u, Vertex v); // Insert edge (u,v) into graph void DeleteVertex(Vertex v); // Delete v and all edges incident to it void DeleteEdge(Vertex u, Vertex v); Delete edge (u,v) from graph bool IsEmpty(); // if graph has no vertices return true List<Vertex> Adjacent(Vertex v); // return list of all vertices adjacent to vertex v }
Adjacency Matrix/List Construction • Note we will be updating these data structures as we call our graph class methods: • InsertVertex(Vertex v) • InsertEdge(Vertex u, Vertex v) • DeleteVertex(Vertex v) • DeleteEdge(Vertex u, Vertex v) • Linked list approach likely more useful over arrays if don’t know beforehand what adding to graph (how many edges, etc).
Weighted Edges • Often see weighted edges on graphs • Common uses: • Distance between vertices • Cost of moving from one vertex to another vertex • Think of vertices as cities – could be real distances or flight costs and want to know shortest/cheapest path • How do we incorporate these weights into our graph representations?
Weighted Edges Could store weights in adjacency matrix (just need a non-zero entry) 0 1 2 3 0 0 60 40 55 1 60 0 0 0 2 40 0 0 50 3 55 0 50 0 If using lists, add another field to node Mehran Ilam 60 1 0 40 Sarableh 2 55 50 3 Ivan
Elementary Graph Operations • First Operation: Traversal of graphs • Already saw how this worked in binary trees (inorder, preorder, postorder, depth-order) • Similar idea for general graphs • Given a graph G = (V,E) and a vertex v in V(G), visit all vertices in G that are reachable from v • This is the subset of the graph that is connected to v.
Graph Traversal • Depth-First Search • Similar to descending down binary tree • Basic algorithm: • Begin by starting at vertex v. • Select an edge from v, say it’s the edge (v,w). • Move to vertex w and recurse. • When a node has been visited that has all of its adjacent vertices visited, back up to the last node with an unvisited adjacent vertex and recurse.
DFS Traversal void Graph::DFS() // driver { visited = new bool[n]; for (int i = 0; i < n; i++) visited[i] = false; DFS(0); delete [] visited; } void Graph::DFS(const int v) // workhorse { visited[v] = true; for (each vertex w adjacent to v) //use adjacency matrix or lists if (!visited[w]) DFS(w); }
DFS Traversal – Graph To Traverse 0 1 2 1 0 3 4 0 2 0 5 6 1 2 3 1 7 4 1 7 3 4 5 6 5 2 7 6 2 7 7 7 3 4 5 6
DFS Traversal Order of Traversal: 0, 1, 3 7, 4, 5, 2, 6 Note that performing DFS can find connected components. In this case, the whole graph is connected and thus all nodes were visited. 0 1 2 3 4 5 6 7
Analysis of DFS – From a single node • Running time dependent on graph structure and representation • If graph G is represented by adjacency lists • Determine vertices adjacent to vertex v by following chain of links. • Each node in each lists is visited at most once, and there are 2*e list nodes. Thus, the running time is bounded by the number of edges. • If graph G is represented by an adjacency matrix • Have to look at n items (n = number of vertices) for each vertex (scanning down each row in the matrix) • Running time is O(n*n).
Breadth First Traversal • Similar to descending across levels of a binary tree. • Visit the starting vertex v. • Visit all unvisited vertices directly adjacent to v. • Recurse, visiting all unvisited vertices directly adjacent to those from the previous step.