1 / 42

Using a Directed Graph

Using a Directed Graph. Drozdek Chapter 8. Objectives. You will be able to Understand and use a C++ ADT for a directed graph. Describe and implement an algorithm for finding the shortest path between two nodes in a directed graph. New Project. New Project.

rahim-koch
Download Presentation

Using a Directed Graph

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Using a Directed Graph Drozdek Chapter 8

  2. Objectives You will be able to • Understand and use a C++ ADT for a directed graph. • Describe and implement an algorithm for finding the shortest path between two nodes in a directed graph.

  3. New Project

  4. New Project

  5. Implementation of a Directed Graph ADT • Download to project directory: • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_04_25_Directed_Graphs/ • Digraph.h • shortest_path.cpp • NetworkFile.txt • Delete .txt from the .h and .cpp files • Add the .h and .cpp files to the project

  6. Implementation of a Directed Graph ADT • Examine Digraph.h • Adjacency list representation. • The Digraph is a vector of Vertex objects • Node ID is the index. • Element 0 is not used. • Each Vertex object has a data member • Template class T • A list of integers (Node IDs) • Nodes adjacent to this node.

  7. NetworkFile.txt • Example: Digraph with string as template parameter. • Class Digraph method read() sets up the digraph with contents of a file.

  8. NetworkFile.txt 1 2 3 4 5 6 7 8 First number in each list is the number of adjacencies. The then IDs of adjacent cities. Note that Denver has an adjacency to itself. (Sight-seeing flight? )

  9. Adjacencies in NetworkFile.txt Bos 5 Chi 4 LA 1 Den 3 NY 6 SF 2 NO 8 Miami 7

  10. Digraph<T>::read() template <typename T> void Digraph<T>::read(ifstream & inStream) { Vertex vi; int n; // number of adjacent vertices int vertex_id; // the number of a vertex // Create a garbage 0-th value so real indices start with 1 digraph.push_back(vi); while (true) { inStream >> vi.data; if (inStream.eof()) break; vi.adjacencyList.clear(); inStream >> n; // Number of adjacent vertices for (int i = 1; i <= n; i++) { inStream >> vertex_id; assert(inStream.good()); vi.adjacencyList.push_back(vertex_id); } digraph.push_back(vi); } }

  11. Digraph<T>::display( ) template <typename T> void Digraph<T>::display(ostream & out) { out << "Adjacency-List Representation: \n"; for (size_t i = 1; i < digraph.size(); i++) { out << i << ": " << digraph[i].data << "--"; for (list<int>::iterator it = digraph[i].adjacencyList.begin(); it != digraph[i].adjacencyList.end(); it++) out << *it << " "; out << endl; } }

  12. Depth First Search • Public method: void depthFirstSearch(int start = 1); ... template <typename T> inline void Digraph<T>::depthFirstSearch(int start) { vector<bool> unvisited(digraph.size(), true); depthFirstSearch(start, unvisited); }

  13. Internal Depth First Search Method // Internal (recursive) depth first search method template <typename T> void Digraph<T>::depthFirstSearch(int start, vector<bool> & unvisited) { visit(digraph[start].data); unvisited[start] = false; // Traverse the adjacency list, performing depth-first // searches from each unvisited vertex in it. list<int>::iterator it; list<int>::iterator begin = digraph[start].adjacencyList.begin(); list<int>::iterator end = digraph[start].adjacencyList.end(); for (it = begin; it != end; it++) { // check if current vertex has been visited if (unvisited[*it]) { // Do a depth first search from this vertex depthFirstSearch(*it, unvisited); } } }

  14. The visit() Method template <typename T> void Digraph<T>::visit(T& node_data) { cout << node_data << endl; } • A Virtual Method • Intended to be overridden in a derived class in order to do something useful at each node.

  15. get_digraph() void get_digraph() { ifstream network_file; while (true) { cout << "Enter name of network file: "; string filename; cin >> filename; network_file.open(filename.c_str()); if (network_file.is_open()) { break; } cout << "Could not open " << filename << endl; cout << "Please try again" << endl; } digraph.read(network_file); network_file.close(); cout << "The Digraph's adjacency list representation:\n"; digraph.display(cout); cout << endl; }

  16. Initial main() int main() { get_digraph(); cout << endl << "Normal termination" << endl; cin.get(); cin.get(); return 0; }

  17. The Adjacency Lists

  18. Depth First Search • Let's do a Depth First Search. int main() { get_digraph(); digraph.depthFirstSearch(); cout << endl << "Normal termination" << endl; cin.get(); cin.get(); return 0; }

  19. Depth First Search from LA

  20. Depth First Search from LA Bos 5 Chi 4 LA 1 Den 3 NY 6 SF 2 NO 8 Miami 7

  21. Depth First Search from Boston • Do a depth first search from Boston. int main() { get_digraph(); digraph.depthFirstSearch(5);

  22. Depth First Search from Boston

  23. Depth First Search from Boston Bos 5 Chi 4 LA 1 Den 3 NY 6 SF 2 NO 8 Miami 7

  24. Providing Our Own Visit Method • Add derived class Digraph2.h • http://www.cse.usf.edu/~turnerr/Data_Structures/Downloads/2011_04_25_Directed_Graphs/ • Delete the .txt

  25. Digraph2.h #pragma once #include "digraph.h" template <typename T> class Digraph2 : public Digraph<T> { public: void visit(T& node_data); }; template <typename T> void Digraph2<T>::visit(T& node_data) { show_length(node_data); } Override visit() method in base class

  26. In shortest_path.cpp #include "Digraph2.h" Digraph2<string> digraph; void show_length(string name) { cout << "Length of " << name << " is " << name.length() << endl; }

  27. Own Visit Method End of Section

  28. Paths • Routing problems – find an optimal path in a network • A shortest path in a digraph. • A cheapest path in a weighted digraph. • Example – a directed graph that models an airline network • Vertices represent cities. • Arcs represent flights connecting cities. • Task: Find most direct route between two cities. • (Fewest flights)

  29. Paths in Directed Graph • Most direct route • Shortest path. • Path from start vertex to destination vertex with minimum number of arcs. • Search algorithm for a shortest path: • A minor modification of the breadth-first search algorithm. • Do a breadth first traversal, keeping track of the predecessor of each node reached. • Stop upon reaching the destination node.

  30. Shortest Path Algorithm • Given a directed graph with nodes 1 to n, a starting node ID, start, and a destination node ID,dest: • Let dist[] be an array of ints • dist[v] will hold the distance from start to node v. • Let pred[] be an array of node IDs. • pred[v] will be the predecessor to node v on a shortest path from start to dest. • Initialize dist[start] to 0 and dist[v] to infinity for all other nodes.

  31. Shortest Path Algorithm • Initialize vertex_queue as a queue of ints, initially containing just the starting vertex ID. • While dest has not been visited and vertex queue is not empty: • Remove the front item from the vertex queueas v. • For each node, w, adjacent to v: • If dist[w] is infinity • Set dist[w] to dist[v]+1 • Set pred[w] to v. • Add w to the vertex queue.

  32. Shortest Path Algorithm • At this point, either we have reached dest or we have exhausted the possibilities. • If dist[dest] is infinity report failure. • Else • Initialize a stack with dest. • Initialize v as dest. • Do the following • Set v to pred[v] • Push v onto the stack • until v is start. • The stack now holds a shortest path from start to dest.

  33. Implementation of Shortest_Path In digraph.h template<typename T> vector<int> Digraph<T>::Shortest_Path(int start, int dest) { int n = digraph.size(); vector<int> dist(n, INT_MAX); // Distance from start vector<int> pred(n, 0); // Predecessor on shortest path int v; // The current vertex queue<int> vertex_queue; vertex_queue.push(start); dist[start] = 0;

  34. Implementation of Shortest_Path while (dist[dest] == INT_MAX && !vertex_queue.empty()) { v = vertex_queue.front(); vertex_queue.pop(); list<int>::iterator it; list<int>::iterator begin = digraph[v].adjacencyList.begin(); list<int>::iterator end = digraph[v].adjacencyList.end(); for (it = begin; it != end; ++it) { int w = *it; if (dist[w] == INT_MAX) { dist[w] = dist[v] + 1; pred[w] = v; vertex_queue.push(w); } } }

  35. Implementation of Shortest_Path // Now reconstruct the shortest path if there is one if (dist[dest] == INT_MAX) { cout << "Destination not reachable from start vertex\n"; return path; } stack<int> reverse_path; reverse_path.push(dest); v = dest; do { v = pred[v]; reverse_path.push(v); } while (v != start);

  36. Implementation of Shortest_Path vector<int> path; while (!reverse_path.empty()) { v = reverse_path.top(); path.push_back(v); reverse_path.pop(); } return path; }

  37. main() int main() { get_digraph(); char response; do { int start, destination; cout << "Number of start city? "; cin >> start; cout << "Number of destination? "; cin >> destination; vector<int> path = digraph.Shortest_Path(start, destination); if (path.size() > 0) { display_path(path); } else { cout << digraph.get_data(destination) << " is unreachable from " << digraph.get_data(start) << endl; } cout << endl << "More (Y or N)?"; cin >> response; }while (response == 'y' || response == 'Y');

  38. Try it!

  39. Computing Shortest Paths

  40. A Defect • What happens if we ask for the shortest path from a city to itself?

  41. A Defect

  42. A Defect • What is the program doing? • What should it do? End of Presentation

More Related