// Source code example for "A Practical Introduction to Data Structures and // Algorithm Analysis" by Clifford A. Shaffer, Prentice Hall, 1998.

Similar documents
ECE4050 Data Structures and Algorithms. Lecture 8: Graphs

Data Structure Lecture#23: Graphs (Chapter 11) U Kang Seoul National University

11.1 Terminology and Representations

Data Structure Lecture#24: Graphs 2 (Chapter 11) U Kang Seoul National University

CS 5114: Theory of Algorithms. Graph Algorithms. A Tree Proof. Graph Traversals. Clifford A. Shaffer. Spring 2014

Graphs. Data Structures 1 Graphs

A Practical Introduction to Data Structures and Algorithm Analysis

CS 5114: Theory of Algorithms. Graph Algorithms. A Tree Proof. Graph Traversals. Clifford A. Shaffer. Spring 2014

The ADT priority queue Orders its items by a priority value The first item removed is the one having the highest priority value

Chapter 14. Graphs Pearson Addison-Wesley. All rights reserved 14 A-1

Graph Applications. Topological Sort Shortest Path Problems Spanning Trees. Data Structures 1 Graph Applications

Basic Graph Definitions

UNIT 5 GRAPH. Application of Graph Structure in real world:- Graph Terminologies:

Lecture 6 Basic Graph Algorithms

CS200: Graphs. Rosen Ch , 9.6, Walls and Mirrors Ch. 14

Part VI Graph algorithms. Chapter 22 Elementary Graph Algorithms Chapter 23 Minimum Spanning Trees Chapter 24 Single-source Shortest Paths

To list all vertices connected to a vertex u in graph G we can use the following loop:

UNIT Name the different ways of representing a graph? a.adjacencymatrix b. Adjacency list

Homework Assignment #3 Graph

CS61B, Fall 2002 Discussion #15 Amir Kamil UC Berkeley 12/5/02

DHANALAKSHMI COLLEGE OF ENGINEERING, CHENNAI. Department of Computer Science and Engineering CS6301 PROGRAMMING DATA STRUCTURES II

CS 341: Algorithms. Douglas R. Stinson. David R. Cheriton School of Computer Science University of Waterloo. February 26, 2019

CS302 - Data Structures using C++

Spanning Trees, greedy algorithms. Lecture 22 CS2110 Fall 2017

Minimum Spanning Trees Ch 23 Traversing graphs

Spanning Trees 4/19/17. Prelim 2, assignments. Undirected trees

Outline. Graphs. Divide and Conquer.

Spanning Trees. Lecture 22 CS2110 Spring 2017

Data Structures Brett Bernstein

Graphs & Digraphs Tuesday, November 06, 2007

Graph Representation DFS BFS Dijkstra A* Search Bellman-Ford Floyd-Warshall Iterative? Non-iterative? MST Flow Edmond-Karp

Practical Session No. 12 Graphs, BFS, DFS, Topological sort

Elementary Graph Algorithms. Ref: Chapter 22 of the text by Cormen et al. Representing a graph:

1. Graph and Representation

10/31/18. About A6, Prelim 2. Spanning Trees, greedy algorithms. Facts about trees. Undirected trees

Spanning Trees, greedy algorithms. Lecture 20 CS2110 Fall 2018

CSI 604 Elementary Graph Algorithms

Minimum Spanning Trees

Algorithm Design and Analysis

Algorithm Analysis Graph algorithm. Chung-Ang University, Jaesung Lee

Data Structures and Algorithms for Engineers

Graphs. Computer Science E-119 Harvard Extension School Fall 2012 David G. Sullivan, Ph.D. What is a Graph? b d f h j

CSE 100 Minimum Spanning Trees Prim s and Kruskal

More Graph Algorithms: Topological Sort and Shortest Distance

Lecture 10. Elementary Graph Algorithm Minimum Spanning Trees

L22-23: Graph Algorithms

Graphs. What is a Graph? Computer Science S-111 Harvard University David G. Sullivan, Ph.D.

Graph Traversals BFS & DFS 1 CS S-16

Total Score /1 /20 /41 /15 /23 Grader

Algorithms and Data Structures 2014 Exercises and Solutions Week 9

Week 12: Minimum Spanning trees and Shortest Paths

Graphs. There is no restriction on the relation E. Directed graphs also known as digraphs


CSC 8301 Design & Analysis of Algorithms: Kruskal s and Dijkstra s Algorithms

Data Structures and Algorithms

Data Structures and Algorithms

Unit 2: Algorithmic Graph Theory

CSE 100: GRAPH ALGORITHMS

ROOT: A node which doesn't have a parent. In the above tree. The Root is A.

Info 2950, Lecture 16

Graph Algorithms. Definition

CSE 100: GRAPH ALGORITHMS

W4231: Analysis of Algorithms

Inf 2B: Graphs, BFS, DFS

CS 125 Section #6 Graph Traversal and Linear Programs 10/13/14

I A graph is a mathematical structure consisting of a set of. I Formally: G =(V, E), where V is a set and E V V.

Practical Session No. 12 Graphs, BFS, DFS Topological Sort

Lecture 5: Graph algorithms 1

Parallel Graph Algorithms

Graph Theory. Many problems are mapped to graphs. Problems. traffic VLSI circuits social network communication networks web pages relationship

Exam 3 Practice Problems

CIS 121 Data Structures and Algorithms Midterm 3 Review Solution Sketches Fall 2018

Graph Traversal CSCI Algorithms I. Andrew Rosenberg

Graph Traversals. CS200 - Graphs 1

Minimum Spanning Trees My T. UF

Graphs. Graph G = (V, E) Types of graphs E = O( V 2 ) V = set of vertices E = set of edges (V V)

Advanced algorithms. topological ordering, minimum spanning tree, Union-Find problem. Jiří Vyskočil, Radek Mařík 2012

CS 310 Advanced Data Structures and Algorithms

Minimum-Spanning-Tree problem. Minimum Spanning Trees (Forests) Minimum-Spanning-Tree problem

CS 206 Introduction to Computer Science II

Algorithms (VII) Yijia Chen Shanghai Jiaotong University

國立清華大學電機工程學系. Outline

Shortest path problems

Problem 1. Which of the following is true of functions =100 +log and = + log? Problem 2. Which of the following is true of functions = 2 and =3?

2. True or false: even though BFS and DFS have the same space complexity, they do not always have the same worst case asymptotic time complexity.

Parallel Graph Algorithms

Graph Algorithms. Andreas Klappenecker. [based on slides by Prof. Welch]

Week 5. 1 Analysing BFS. 2 Depth-first search. 3 Analysing DFS. 4 Dags and topological sorting. 5 Detecting cycles. CS 270 Algorithms.

Dist(Vertex u, Vertex v, Graph preprocessed) return u.dist v.dist

CS 270 Algorithms. Oliver Kullmann. Breadth-first search. Analysing BFS. Depth-first. search. Analysing DFS. Dags and topological sorting.

Algorithms (VII) Yijia Chen Shanghai Jiaotong University

CS 270 Algorithms. Oliver Kullmann. Analysing BFS. Depth-first search. Analysing DFS. Dags and topological sorting.

Chapter 5. Decrease-and-Conquer. Copyright 2007 Pearson Addison-Wesley. All rights reserved.

Undirected Graphs. Hwansoo Han

CSE373: Data Structures & Algorithms Lecture 17: Minimum Spanning Trees. Dan Grossman Fall 2013

COMPSCI 311: Introduction to Algorithms First Midterm Exam, October 3, 2018

( ) ( ) C. " 1 n. ( ) $ f n. ( ) B. " log( n! ) ( ) and that you already know ( ) ( ) " % g( n) ( ) " #&

Three Graph Algorithms

Three Graph Algorithms

MST & Shortest Path -Prim s -Djikstra s

Transcription:

// Source code example for "A Practical Introduction to Data Structures and // Algorithm Analysis" by Clifford A. Shaffer, Prentice Hall, 1998. // Copyright 1998 by Clifford A. Shaffer

// graph.java 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 Vertices identified by an integer i (0 <= i <= G.n()) Edges have a double nature: Seen as pairs of vertices or as an aggregate objects. //Edge.java 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 // Edgem.java // Edge class for Adjacency Matrix graph representation class Edgem implements Edge { private int vert1, vert2; // The vertex indices public Edgem(int v int vt2) { vert1 = vt1; vert2 = vt2; t1, public int v1() { return vert1; public int v2() { return vert2; // class Edgem

//Graphm.java 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) { Mark = new int[n]; matrix = new int[n][n]; numedge = 0; // Constructor 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(int i=0; i<mark.length; i++)// (i.e. with the lowest v2 if (matrix[v][i]!= 0) // value) for a vertex v 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; 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){ return w.v1(); // Where edge comes from public int v2(edge w){ return w.v2(); // Where edge goes to

public void setedge(int i, int j, int wt) { // Set edge weight matrix[i][j] = wt; numedge++; public void setedge(edge w, int weight) // Set edge weight { if (w!= null) setedge(w.v1(), w.v2(), weight); 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--; 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 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

Graph Traversals Some applications require visiting every vertex in the graph exactly once. Application may require that vertices be visited in some special order based on graph topology. To insure visiting all the vertices of the connected components of the graph: void graphtraverse(graph G) { for (v=0; v<g.n(); v++) G.setMark(v, UNVISITED); // Initialize mark bits for (v=0; v<g.n(); v++) if (G.getMark(v) == UNVISITED) dotraverse(g, v); // see below DFS or BFS Depth First Search (DFS) Whenever a vertex v is visited during the search, recursively visit all of its unvisited neighbours. The process creates a depth-first search tree. This tree is composed of edges that were followed to any new, unvisited, vertex during the traversal; and leaves out the edges that lead to already visited vertices. // Depth first search (starting from vertex v) 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

Breadth First Search (BFS) Like DFS, but replace stack with a queue. Visit the vertex's neighbours before continuing deeper in the tree. BFS is implemented similarly to DFS, except that a queue replaces the recursion stack. static void BFS(Graph G, int start) { Queue Q = new AQueue(G.n()); // Use a Queue Q.enqueue(new Integer(start)); G.setMark(start, VISITED); while (!Q.isEmpty()) { // Process each vertex on Q int v = ((Integer)Q.dequeue()).intValue(); 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(new Integer(G.v2(w))); PostVisit(G, v); // Take appropriate action Starting at A and visiting adjacent neighbours in lexicographic order:

Topological Sort Problem: Given a set of jobs, courses, etc with prerequisite constraints, output the jobs in a linear order that allow us to complete them one at time without violating any prerequisites. The problem is modelled using a Directed Acyclic Graph (DAG) Example of acceptable sort: J1, J2, J3, J4, J5, J6, J7 One kind of Topological sort is obtained visiting the graph by means of a DFS with a post order manipulation and subsequently reversing the list obtained. Starting at J1 and visiting adjacent neighbours in lexicographic order: Reverse(J7, J5, J4, J6, J2, J3, J1) = J1, J3, J2, J6, J4, J5, J7 static void topsort(graph G) { // Topological sort: recursive for (int i=0; i<g.n(); i++) // Initialize Mark array G.setMark(i, UNVISITED); for (int i=0; i<g.n(); i++)//process all vertices for all //connected components of the graph if (G.getMark(i) == UNVISITED) tophelp(g, i); // Call helper function static void tophelp(graph G, int v) { // Topsort helper G.setMark(v, VISITED); for (Edge w = G.first(v); G.isEdge(w); w = G.next(w)) if (G.getMark(G.v2(w)) == UNVISITED) tophelp(g, G.v2(w)); printout(v); // PostVisit for Vertex v

A Queue-based Topological Sort: first visit all the edges counting the number of edges that leads to each vertex. All vertices without incoming edges are placed on the queue. While the queue is not empty 1. Take off a vertex from the queue and print it 2. Decrease the counts of all its neighbours o Each vertex with zero incoming edge is placed on the queue static void topsort(graph G) { // Topological sort: Queue Queue Q = new AQueue(G.n()); int[] Count = new int[g.n()]; int v; for (v=0; v<g.n(); v++) // Initialize Count[v] = 0; for (v=0; v<g.n(); v++) // Process every edge for (Edge w=g.first(v); G.isEdge(w); w=g.next(w)) Count[G.v2(w)]++; // Add to v2's count for (v=0; v<g.n(); v++) if (Count[v] == 0) Q.enqueue(new Integer(v)); // Initialize Queue // Vertex has no prereqs while (!Q.isEmpty()) { // Process the vertices v = ((Integer)Q.dequeue()).intValue(); printout(v); // PreVisit for Vertex V for (Edge w=g.first(v); G.isEdge(w); w=g.next(w)) { Count[G.v2(w)]--; // One less prerequisite if (Count[G.v2(w)] == 0) // This vertex now free Q.enqueue(new Integer(G.v2(w)));

Shortest Paths Problems Input: A graph with weights or costs associated with each edge. Output: The list of edges forming the shortest path. Problems: - Find the shortest path between two specified vertices. - Find the shortest path from vertex S to all other vertices (is the worst case of the previous problem) - Find the shortest path between all pairs of vertices. (For sake of simplicity, our algorithms will actually calculate only distance rather than recording the actual path.) d(a, B) is the shortest distance from vertex A to B. w(a, B) is the weight of the edge connecting A to B. -- If there is no such edge, then w(a, B) = INFINITY. Single Source Shortest Paths Given start vertex s, find the shortest path from s to all other vertices. Try 1: Visit all vertices in some order, compute shortest paths for all vertices seen so far, then add the shortest path to next vertex x. Problem: The true Shortest path to a vertex already processed might go through x. Solution: Process vertices in order of distance from s. Dijkstra Algorithm Maintain a distance estimate for all vertices in the graph: D[v]. Assume that we have processed in order of distance the first i-1 vertices closest to ; call it S. When processing the i-th closest vertex x, the shortest path from s to x must have its next-to-last vertex in S; Thus: d(s,x) = min(d(s,u)+w(u,x)) for all u in S The shortest path from s to x is the minimum over all paths that go from s to u, then have an edge from u to x, where u belongs to S. Whenever a vertex x is processed, D[v] is updated for every neighbour v of x.

// Dijkstra's Algorithm: Array // Compute shortest path distances from s, store in D static void Dijkstra(Graph G, int s, int[] D) { for (int i=0; i<g.n(); i++) // Initialize D[i] = Integer.MAX_VALUE; D[s ] = 0; for (int i=0; i<g.n(); i++) { // Process vertices int v = minvertex(g, D); // Get next-closest vertex G.setMark(v, VISITED); if (D[v] == Integer.MAX_VALUE) return; for (Edge w=g.first(v); G.isEdge(w); w=g.next(w)) if (D[G.v2(w)] > (D[v] + G.weight(w))) D[G.v2(w)] = D[v] + G.weight(w); Issue: How to determine the next-closest vertex? (I.e., implement minvertex) Approach 1: Scan through the table of current distances. Cost: Q( V 2 + E ) = Q( V 2 ) static int minvertex(graph G, int[] D) { int v = 0; // Initialize v to any unvisited vertex; for (int i=0; i<g.n(); i++) if (G.getMark(i) == UNVISITED) { v = i; break; for (int i=0; i<g.n(); i++) // Find smallest value if ((G.getMark(i) == UNVISITED) && (D[i] < D[v])) v = i; return v;

Approach 2: Store unprocessed vertices using a min-heap to implement a priority queue ordered by D value. Must update priority queue for each edge. Cost: Q( ( V + E ) log V ) We need to store on the heap some object that implements Elem interface (i.e. with a key method) and stores a vertex and its current distance from the start vertex. The key method returns the distance from the start vertex. interface Elem { // Interface for generic element type public abstract int key(); // Key used for search and ordering // interface Elem class DijkElem implements Elem { private int vertex; private int distance; public DijkElem(int v, int d) { vertex = v; distance = d; public DijkElem() {vertex = 0; distance = 0; public int key() { return distance; public int vertex() { return vertex; // class DikjElem // Dijkstra's shortest-paths algorithm: // prio rity queue version static void Dijkstra(Graph G, int s, int[] D) { int v; // The current vertex DijkElem[] E = new DijkElem[G.e()]; // Heap: array of edges E[0] = new DijkElem(s, 0); // Initialize array MinHeap H = new MinHeap(E, 1, G.e()); // Create heap from array E // with currently 1 element // out of G.e() for (int i=0; i<g.n(); i++) // Initialize distances D[i] = Integer.MAX_VALUE; D[s ] = 0; for (int i=0; i<g.n(); i++) { // For each vertex do { v = ((DijkElem)H.removemin()).vertex(); while (G.getMark(v) == VISITED); /// Now we have Extracted the minimum UNVISITED vertex v G.setMark(v, VISITED); if (D[v] == Integer.MAX_VALUE) return; for (Edge w=g.first(v); G.isEdge(w); w=g.next(w)) if (D[G.v2(w)] > (D[v] + G.weight(w))) { // Update D D[G.v2(w)] = D[v] + G.weight(w); H.insert(new DijkElem(G.v2(w), D[G.v2(w)]));

All Pairs Shortest Paths For every vertex (u; v), calculate d(u, v). Could run Dijkstra's Algorithm V times. Better is Floyd's Algorithm. [The issue is how to efficiently check all the paths without computing any path more than once.] Define a k-path from u to v to be any path whose intermediate vertices all have indices less than k (aside u and v). The shortest path between u, v will be an n-path. 0-path between u,v is weight of edge[u, v] Path 3-0-2 is a 1-path; Path 1-3-2 is a 4-path If D k [u,v] is the shortest k-path between u and v then The shortest k+1 path between u and v either goes through vertex k or it does not. If it goes through vertex k, then such a path is constructed as the shortest k-path between u and k followed by the shortest k-path between k and v. If it does not go through vertex k, then D k+1 [u,v] = D k [u,v]. // Floyd's Algorithm: Compute all-pairs shortest paths in matrix D static void Floyd(Graph G, int[][] D) { for (int i=0; i<g.n(); i++) // Initialize D with 0-paths for (int j=0; j<g.n(); j++)// amid all couples of vertices D[i][j] = G.weight(i, j); for (int k=0; k<g.n(); k++) // Compute all k paths for (int i=0; i<g.n(); i++) for (int j=0; j<g.n(); j++) if ( (D[i][k]!= Integer.MAX_VALUE) && (D[k][j]!= Integer.MAX_VALUE) && (D[i][j] > (D[i][k] + D[k][j])) ) D[i][j] = D[i][k] + D[k][j];

Minimum Cost Spanning Trees Minimum Cost Spanning Tree (MST) Problem: Input: An undirected, connected graph G. Output: The subgraph of G that o 1) has minimum total cost as measured by summing the values for all of the edges in the subset, and o 2) keeps the vertices connected. Prim's MST Algorithm This is an example of a greedy algorithm. Starting from any vertex N in the graph; Add it to the MST; Search for the minimum edge that comes from N to a vertex out of the MST, call it M Insert M and the selected edge e 1 to the MST Search for the minimum edge that comes from N or M to a vertex out of the MST,call it P Insert P and the selected edge e 2 to the MST Repeat the same steps until all the vertex in the graph have been visited.

// Compute a minimal-cost spanning tree // D[i], respect to vertex i, stores the distance from the closest // vertex in the MST static void Prim(Graph G, int s, int[] D) { int[] V = new int[g.n()]; // V[i] closest MST vertex to i for (int i=0; i<g.n(); i++) // Initialize D[i] = Integer.MAX_VALUE; D[s] = 0; for (int i=0; i<g.n(); i++) { // Process vertices int v = minvertex(g, D); G.setMark(v, VISITED); if (v!= s) System.out.println("Add Edge " + V[v] + ", " + v); if (D[v] == Integer.MAX_VALUE) return; 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); V[G.v2(w)] = v;