490 likes | 593 Views
Chapter 14. Graphs. Chapter Outline. Objectives Follow and explain graph-based algorithms using the usual computer science Design and implement classes for labeled or unlabeled graphs List the order in which nodes are visited for the two common graph traversals and implement these algorithms
E N D
Chapter 14 Graphs
Chapter Outline • Objectives • Follow and explain graph-based algorithms using the usual computer science • Design and implement classes for labeled or unlabeled graphs • List the order in which nodes are visited for the two common graph traversals and implement these algorithms • Simulate the steps of simple path algorithms and be able to design and implement such algorithms • Contents • Graph Definitions • Graph Implementations • Path algorithms Data Structure
Graph Definitions • A graph is a nonlinear data structure consisting of nodes and links between the nodes • Graph nodes can be linked in any pattern or lack of pattern depending only on the needs of an application Data Structure
Undirected Graphs • Is a finite set of vertices together with a finite set of edges • Each node is called a vertex, each link is called an edge • Each edge is associated with two vertices • We sometimes say that the edge connects its two vertices v0 e0 e5 e1 v1 v2 e4 e2 v4 v3 e3 Data Structure
Programming Example: Unidirected State Graphs • See the page 691 ~ 693 Data Structure
Directed Graphs • Each edge has an orientation connecting its first vertex(called the edge’s source to its second vertex(the edge’s target) • Are drawn as diagrams with circles representing the vertices and arrows representing the edges Data Structure
More graph terminology • Loop • Is an edge that connects a vertex to itself • Path • Is a sequence of vertices, P0, P1 … Pm • Multiple Edges • Graph can have two or more edges connecting the same two vertices in the same direction • Simple Graphs • Have no loops and no multiple edges • Example : Page 696 Data Structure
1 0 3 2 Graph implementations • Representing Graphs with an adjacency matrix 0 1 2 3 0 1 2 3 true false true false true false false false true false false true true false true false • Adjacency Matrix • Is square grid of true/false values that represent the edges of a graph • If the graph contains n vertices, the the grid contains n rows and n columns Data Structure
Graph implementations • Using a Two-dimensional array to store an adjacency matrix • An adjacency matrix can be stored in a two-dimensional array • double[][] budget; • budget[2][6] = 3.14; Data Structure
1 0 3 2 Graph implementations • Representing graphs with edges lists Edge list for vertex 2 Edge list for vertex 0 Edge list for vertex 1 Edge list for vertex 3 null 1 1 0 2 3 2 null null null Data Structure
Graph implementations • Representing graphs with edges sets • Suppose we have declared IntSet as a class capable of holding a set of integers • To represent a graph with 10 vertices • IntSet[] connections = new IntSet[10]; Data Structure
Graph implementations • Which Representation Is Best? • If the space is available, an adjacency matrix is easier to implement and is generally easier to use • Consider the following operations • Adding or removing edges • Checking whether a particular edge is present • Iterating a loop that executes one time for each edge with a particular source vertex • Consider the average number of edges originating at a vertex Data Structure
Programming example: Labeled Graph ADT public class Graph { private boolean[][] edges; private Object[] labels; } • Constructor for the Graph • public Graph(int n) • Initialize a Graph with n vertices, no edges, and null labels • Parameters • n – the number of vertices for this Graph • Precondition : n >= 0 • Postcondition • This Graph has n variables, numbered from 0 to n-1. It has no edges and all vertex labels are null Data Structure
Programming example: Labeled Graph ADT • addEdges-and-isEdge-and-removeEdge • public void addEdge(int source, int target) • public void boolean isEdge(int source, int target) • public void removeEdge(int source, int target) • Add an edge, test whether an edge exists, or remove an edge of this Graph • parameters: • source-the vertex number of the source of the edge • target-the vertex number of the target of the edge • Precondition • Both source and target are non-negative and less than size() • Postcondition • For addEdge, the specified edge is added to this Graph • For isEdge, the return value is true if the specified edge exists and is false otherwise Data Structure
Programming example: Labeled Graph ADT • getLabel • public Object getLabel(int vertex) • Accessor method to get the label of a vertex of this Graph • Precondition • vertex is non-negative and less than size() • Returns • the label of the specified vertex in this Graph • setLabel • public voide setlabel(int vertex, Object newLabel) • Change the label of a vertex of this Graph • Precondition • vertex is non-negative and less than size() • Postcondition • The label of the specified vertex in this Graph has been chaged to newlabel Data Structure
Graph traversals • Two common way of traversing a graph • Breadth-first search • Uses a queue to keep track of vertices that still need to be visited • Depth-first search • Uses a stack • Can be implemented recursively in a way that does not explicitly use a stack of vertices • Purpose • To start at one vertex of a graph(the “start” vertex), process the information contained at that vertex • move along an edge to process a neighbor • When the traversal finishes, all of the vertices that can be reached from the start vertex have been processed Data Structure
Graph traversals • It does not enter a repetitive cycle • To prevent this “spinning your wheels” • include an ability to mark each vertex as it is processed v0 The shaded vertex has already been processed by the traversal v2 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search • After processing vertex 0, moves along a directed edge to one of vertex 0’s neighbors v0 The shaded vertex has already been processed v2 v1 v4 v6 v3 v5 Data Structure
v0 v2 v1 v4 v6 v3 v5 Graph traversals • Depth-First search v0 v2 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search v0 v2 v1 v4 v6 v3 v5 Since vertex 5 has no neighbors, the traversal comes back to see if the previous has any more unmarked neighbors v0 v2 v1 Does v3 have any more unmarked neighbors? v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search v0 v2 v1 v4 v6 v3 v5 Since vertex 6 does have a neighbor-vertex 1 But v1 has already been marked. Traversal again backs up to see if v3 has any more unmarked neighbors v0 v2 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search v0 v2 Since vertex 3 has no more unmarked neighbors. So back we go to the previous vertex- vertex1 v1 v4 v6 v3 v5 Since vertex1 has no more unmarked neighbors. we to to vertex 0 v0 v2 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search v0 v2 From vertex 0, We can still travel to the unmarked vertex 4 v1 v4 v6 v3 v5 v0 v2 Vertex 0 has no more unmarked neighbors. That’s end of the traversal v1 v4 v6 v3 v5 Data Structure
Graph traversals • Depth-First search • A traversal processes only those vertices that can be reached from the start vertex • From the start, proceeds to a neighbor and from there to another neighbor.. as far as possible before it ever backsup • This seems as if there’s a lot to keep track of: Where we start, Where we go from there, and where we go from there • Solve by using a recursion to keep track of most of these details in a simple way Data Structure
Graph traversals • Breadth-First Search • Uses a queue to keep track of which vertices might still have unprocessed neighbors • The search begins with a starting vertex, which is processed, marked, and placed in the queue v0 Rear Front v2 v0 v1 v4 A queue of vertices keeps track of which vertices may have unprocessed neighbors v6 v3 v5 Data Structure
Graph traversals • Breadth-First Search • Remove a vertex, v, from the front of the queue • For each unmarked neighbor u of v: Process u, mark u, and then place u in the queue v0 Rear Front v2 v4 v1 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Breadth-First Search v0 Rear Front v2 v3 v4 v1 v4 v6 v3 v5 v0 Rear Front v2 v3 v1 v4 v6 v3 v5 Data Structure
Graph traversals • Breadth-First Search v0 Rear Front v2 v6 v5 v1 v4 v6 v3 v5 Data Structure
Depth-First Search-Implementation • DepthFirstPrint • public static void depthFirstPrint(Graph g, int start) • Static method to print the labels of a graph with a depth-first search • Parameters • g – a non-null Graph • start – a vertex number from the Graph g • Precondition • start is non-negative and less than g.size() • Postcondition • A depth-first search of g has been conducted, starting at the specified start vertex, Each vertex visited has its label printed using System.out.println Data Structure
Depth-First Search-Implementation • depthFirstRecurse • public static void depthFirstRecurse(Graph g, int v, boolean[] marked) • Recursive method to carry out the work of depthFirstPrint • Precondition: • v is non-negative and less than g.size(). • maked.length is equal to g.size(); • for each vetex x of g, marked[x] is true if x has already been visited by this search • Postcondition: • The depth-first search of g has been continued through vertex v and beyond to all vertices that can be reached from v via a path of unmarked vertices Data Structure
Depth-First Search-Implementation public static void depthFirstRecurse(Graph g, int v, boolean[] marked) { int[] connections = g.neighbors(v); int i; int nextNeighbor; marked[v] = true; System.out.println(g.getLabel(v)); for (i=0; i<connections.length; i++) { nextNeighbor = connections[i]; if (!marked[nextNeighbor]) depthFirstRecurse(g, nextNeighbor, marked); } } Data Structure
Depth-First Search-Implementation public static void depthFirstPrint(Graph g, int start) { boolean[] marked = new boolean[g.size()]; depthFirstRecurse(g, start, marked); } Data Structure
Path algorithms • Determining whether a Path exists • Breadth-first search or a depth first search can be used to determine whether a path exists between two vertices, u and v • The idea • to use u as the start vertex of the search and proceed with a breadth-first or depth-first search • If vertex v is ever visited, then the search can stop and announce that there is a path from u to v Data Structure
Path algorithms • Graphs with Weighted edges • Each edge represents a communication wire between machines • Such a wire might have a “cost” associated with using the wire • There could be many paths from one vertex to another • We might want to find the path with the lowest total cost Solved by using a graph in which each edge has weight or cost of the edge Data Structure
Path algorithms • Graphs with Weighted edges V0 6 1 3 V1 V3 2 7 V2 • For example : There are several paths from vertex v0 to v2 • - Weight of path : The total sum of the weights of all the edges • in the path • Shortest path : The path with the lowest total cost Data Structure
Shortest Distance Algorithm • Dijkstra’s algorithm • Finds the weight of the shortest path • Shortest distance • Provides the shortest distance from a starting vertex to every vertex in the graph • Goal of the shortest distance algorithm • Is to completely fill the distance array so that for each vertex v, the value of distance[v] is the weight of the shortest path from start to v Data Structure
Shortest Distance Algorithm • Dijkstra’s algorithm V0 9 2 6 V5 V1 The starting vertex is v0 15 3 8 V3 1 3 V4 V2 7 Weight of the shortest path from the start vertex to the start vertex itself distance [0] [1] [2] [3] [4] [5] Data Structure
Shortest Distance Algorithm • Three steps for the complete algorithm • Step1 • Fill in the distance array with ∞ at every location with the exception of distance[start], which is assigned the value zero • Step2 • Initialize a set of vertices, called allowedVertices, to be the empty set • a permitted path is a path that starts at the start vertex and in which each vertex on the path is in the set of allowed vertices • Step3 • Loop • Each time through the loop we will add one more vertex to allowedVertices and then update the distance array so all the allowed vertices may appear on paths Data Structure
Shortest Distance Algorithm • Step3 • for (allowedSize = 1; allowedSize <= n; allowedSize++) { Step 3a. Let next be the closest vertex to the start vertex that is not yet in the set of allowed vertices. Step 3b. Add the vertex next to the set allowedVertices Step 3c. Revise the distance array so the new vertex (next) may appear on permitted paths } Data Structure
Shortest Distance Algorithm • Step 3a. • must determine which of the unallowed vertices is closest to the start vertex • Rule for choosing vertex • choose the unallowed vertex that has the smallest current value in the distance array distance [0] [1] [2] [3] [4] [5] - The two shaded vertices, 0 and 1 are already in the set of allowed vertices - choose the vertex 5 Data Structure
V0 9 2 6 V5 V1 15 8 V3 3 1 V4 V2 7 Shortest Distance Algorithm • Step 3b. • add the vertex next to the set allowedVertices • Step 3c. • suppose vertices 0, 1 and 5 are already in the allowedVertices set, and we added vertex 2 as our next vertex distance [0] [1] [2] [3] [4] [5] 3 Data Structure
Shortest Distance Algorithm • Step 3c. • distance[3] is 17 • There is a path from the start vertex to vertex 3 that uses only vertices 0, 1, and 5 • If we also allow vertex 2 to appear on a path from the start vertex to vertex 3, can we obtain a distance that is smaller than 17? V0 Total weight = distance[2] + (weight of edge from vertex 2 to vertex 3) = 11 9 2 6 V5 V1 15 3 We should replace distance[3] with this smaller sum. 8 V3 3 1 V4 V2 Data Structure 7
Shortest Distance Algorithm • Step 3c (revised). • Revise the distance array so that the new vertex (next) may appear on permitted paths First time V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 The value of next is set to vertex 0 then look at each unallowed vertex v with an edge from vertex 0 to vertex v => vertices 1 and 5 distance[0] + (weight of the edge from 0 to 1) = 2 distance[0] + (weight of the edge from 0 to 5) = 9 Data Structure
Shortest Distance Algorithm V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 Data Structure
Shortest Distance Algorithm Second time The value of next is set to vertex 1 then look at each unallowed vertex v with an edge from vertex 0 to vertex v => vertices 2, 3, 5 distance[1] + (weight of the edge from 1 to 2) = 10 distance[1] + (weight of the edge from 1 to 3) = 17 distance[1] + (weight of the edge from 1 to 5) = 8 V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 Data Structure
Shortest Distance Algorithm Third time The value of next is set to vertex 5 then look at each unallowed vertex v with an edge from vertex 0 to vertex v => vertices 4 distance[5] + (weight of the edge from 5 to 4) = 11 V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 Data Structure
Shortest Distance Algorithm Fourth Time The value of next is set to vertex 2 then look at each unallowed vertex v with an edge from vertex 0 to vertex v => vertices 3 distance[2] + (weight of the edge from 2 to 3) = 11 V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 Data Structure
Shortest Distance Algorithm Fifth Time The value of next is set to vertex 4 then look at each unallowed vertex v with an edge from vertex 0 to vertex v => vertices 3 distance[4] + (weight of the edge from 4 to 3) = 14 V0 9 2 distance 6 V5 V1 15 3 8 V3 3 1 [0] [1] [2] [3] [4] [5] V4 V2 7 Data Structure
Shortest path algorithm • How can we compute the actual sequence of vertices that occurs along the shortest path? • Use a predecessor array value • For each vertex v, predecessor[v] is the value of next at the time when distance[v] is the value of next at the time when distance[v] was given a new smaller value vertexOnPath = v; System.out.println(vertexOnPath); while (vertexOnpath != start) { vertexOnPath = predecessor[vertexOnpath]; System.out.println(vertexOnPath); } Data Structure