+ All Categories
Home > Documents > Using a Directed Graph

Using a Directed Graph

Date post: 03-Jan-2016
Category:
Upload: rahim-koch
View: 52 times
Download: 3 times
Share this document with a friend
Description:
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. - PowerPoint PPT Presentation
42
1 Using a Directed Graph Drozdek Chapter 8
Transcript
Page 1: Using a Directed Graph

1

Using a Directed Graph

Drozdek Chapter 8

Page 2: Using a Directed Graph

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.

Page 3: Using a Directed Graph

3

New Project

Page 4: Using a Directed Graph

4

New Project

Page 5: Using a Directed Graph

5

Implementation of a Directed Graph ADT

Download to project directory: http://www.cse.usf.edu/~turnerr/Data_Structures/Dow

nloads/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

Page 6: Using a Directed Graph

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.

Page 7: Using a Directed Graph

7

NetworkFile.txt

Example: Digraph with string as template parameter.

Class Digraph method read() sets up the digraph with contents of a file.

Page 8: Using a Directed Graph

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? )

Page 9: Using a Directed Graph

9

Adjacencies in NetworkFile.txt

LA

1

SF

2

Den

3

Chi

4

Bos

5

NY

6

Miami

7

NO

8

Page 10: Using a Directed Graph

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);

}

}

Page 11: Using a Directed Graph

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;

}

}

Page 12: Using a Directed Graph

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);

}

Page 13: Using a Directed Graph

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);

}

}

}

Page 14: Using a Directed Graph

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.

Page 15: Using a Directed Graph

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;

}

Page 16: Using a Directed Graph

16

Initial main()

int main()

{

get_digraph();

cout << endl << "Normal termination" << endl;

cin.get();

cin.get();

return 0;

}

Page 17: Using a Directed Graph

17

The Adjacency Lists

Page 18: Using a Directed Graph

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;

}

Page 19: Using a Directed Graph

19

Depth First Search from LA

Page 20: Using a Directed Graph

20

Depth First Search from LA

LA

1

SF

2

Den

3

Chi

4

Bos

5

NY

6

Miami

7

NO

8

Page 21: Using a Directed Graph

21

Depth First Search from Boston

Do a depth first search from Boston.

int main()

{

get_digraph();

digraph.depthFirstSearch(5);

Page 22: Using a Directed Graph

22

Depth First Search from Boston

Page 23: Using a Directed Graph

23

Depth First Search from Boston

LA

1

SF

2

Den

3

Chi

4

Bos

5

NY

6

Miami

7

NO

8

Page 24: Using a Directed Graph

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

Page 25: Using a Directed Graph

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

Page 26: Using a Directed Graph

26

In shortest_path.cpp

#include "Digraph2.h"

Digraph2<string> digraph;

void show_length(string name)

{

cout << "Length of " << name << " is "

<< name.length() << endl;

}

Page 27: Using a Directed Graph

27

Own Visit Method

End of Section

Page 28: Using a Directed Graph

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)

Page 29: Using a Directed Graph

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.

Page 30: Using a Directed Graph

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.

Page 31: Using a Directed Graph

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 queue as 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.

Page 32: Using a Directed Graph

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.

Page 33: Using a Directed Graph

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;

Page 34: Using a Directed Graph

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);

}

}

}

Page 35: Using a Directed Graph

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);

Page 36: Using a Directed Graph

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;

}

Page 37: Using a Directed Graph

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');

Page 38: Using a Directed Graph

38

Try it!

Page 39: Using a Directed Graph

39

Computing Shortest Paths

Page 40: Using a Directed Graph

40

A Defect

What happens if we ask for the shortest path from a city to itself?

Page 41: Using a Directed Graph

41

A Defect

Page 42: Using a Directed Graph

42

A Defect

What is the program doing?

What should it do?

End of Presentation


Recommended