0% found this document useful (0 votes)
4 views32 pages

CH 13 Graphs

Uploaded by

banir71284
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views32 pages

CH 13 Graphs

Uploaded by

banir71284
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

7/20/2024

CHAPTER 13 Graphs
• Introduction to Graphs
• Searches
• Minimum Spanning Trees
• Topological Sorting with Directed Graphs
• Connectivity in Directed Graphs

1 2

Figure 13.1a shows a simplified


map of the freeways in the vicinity Figure 13.1b shows a graph that
of San Jose, California. models these freeways.

3 4

3 4

Adjacency Paths
Two vertices are said to be adjacent to one another if they are A path is a sequence of edges. Figure 13.1 shows a path from
connected by a single edge. Thus, in Figure 13.1, vertices I and G vertex B to vertex J that passes through vertices A and E. We can
are adjacent, but vertices I and F are not. call this path BAEJ. There can be more than one path between two
vertices; another path from B to J is BCDJ.

5 6

5 6

1
7/20/2024

Connected Graphs
A graph is said to be connected if there is at least one path from
every vertex to every other vertex, as in the graph in Figure 13.2a. Directed and Weighted Graphs
The graphs in Figures 13.1 and 13.2 are non-directed graphs. That
A non-connected graph consists of several connected components. means that the edges don’t have a direction; you can go either way
In Figure 13.2b, A and B are one connected component, and C and on them. Thus, you can go from vertex A to vertex B, or from vertex B
D are another. to vertex A, with equal ease. (Non-directed graphs model freeways
appropriately, because you can usually go either way on a freeway.)
7 8

7 8

However, graphs are often used to model situations in which you In some graphs, edges are given a weight, a number that can
can go in only one direction along an edge—from A to B but represent the physical distance between two vertices, or the
not from B to A, as on a one-way street. Such a graph is said time it takes to get from one vertex to another, or how much it
to be directed. The allowed direction is typically shown with an costs to travel from vertex to vertex (on airline routes, for
arrowhead at the end of the edge. example). Such graphs are called weighted graphs.

9 10

9 10

The problem, much discussed by the townsfolk, was to find a


Historical Note way to walk across all seven bridges without re-crossing any
One of the first mathematicians to work with graphs was of them. We won’t recount Euler’s solution to the problem; it
Leonhard Euler in the early eighteenth century. He solved a turns out that there is no such path. However, the key to his
famous problem dealing with the bridges in the town of solution was to represent the problem as a graph, with land
Konigsberg, Poland. This town included an island and seven areas as vertices and bridges as edges, as shown in Figure
bridges, as shown in Figure 13.3a. 13.3b.

11 12

11 12

2
7/20/2024

Representing a Graph in a Program class Vertex


Vertices {
public char label; // (e.g. ‘A’)
In most situations, however, a vertex represents some real-world public boolean wasVisited;
object, and the object must be described using data items. If a
vertex represents a city in an airline route simulation, for public Vertex(char lab) // constructor
example, it may need to store the name of the city, its altitude, {
its location, and other such information. Thus, it’s usually label = lab;
convenient to represent a vertex by an object of a vertex wasVisited = false;
} Our example programs store only a
class.
} // end class Vertex letter (like A), used as a label for
identifying the vertex, and a flag for use
in search algorithms, as we’ll see later.
Vertex objects can be placed in an array and referred to using their index
number. In our examples we’ll store them in a vector called vertexList.
The vertices might also be placed in a list or some other data structure.
Whatever structure is used, this storage is for convenience only. It has no
relevance to how the vertices are connected by edges. For this, we need
13 another mechanism. 14

13 14

Edges To model this sort of free-form organization, a different approach


A graph, however, doesn’t usually have the same kind of fixed to representing edges is preferable to that used for trees. Two
organization as a tree. In a binary tree, each node has a methods are commonly used for graphs: the adjacency matrix
maximum of two children, but in a graph each vertex may be and the adjacency list. (Remember that one vertex is said to
connected to an arbitrary number of other vertices. For be adjacent to another if they’re connected by a single edge.)
example, in Figure 13.2a, vertex A is connected to three other
vertices, whereas C is connected to only one.

15 16

15 16

The Adjacency Matrix The Adjacency List


An adjacency matrix is a two-dimensional array in which the The other way to represent edges is with an adjacency list. An
elements indicate whether an edge is present between two adjacency list is an array of lists (or sometimes a list of lists).
vertices. If a graph has N vertices, the adjacency matrix is an Each individual list shows what vertices a given vertex is
NxN array. Table 13.1 shows the adjacency matrix for the adjacent to. Table 13.2 shows the adjacency lists for the
graph in Figure 13.2a. graph of Figure 13.2a.

17 20

17 20

3
7/20/2024

Adding Vertices and Edges to a Graph If you are using an adjacency matrix and want to add an edge
To add a vertex to a graph, you make a new vertex object with between vertices 1 and 3. These numbers correspond to the
new and insert it into your vertex array, vertexList. In a real- array indices in vertexList where the vertices are stored.
world program a vertex might contain many data items, but for When you first created the adjacency matrix, you filled it with 0s.
simplicity we’ll assume that it contains only a single character. To insert the edge, you say
Thus, the creation of a vertex looks something like this:
adjMat[1][3] = 1;
vertexList[nVerts++] = new Vertex(‘F’); adjMat[3][1] = 1;

This inserts a vertex F, where nVerts is the number of vertices If you were using an adjacency list, you would add a 1 to the list
currently in the graph. for 3, and a 3 to the list for 1.

21 22

21 22

class Graph
The Graph Class {
Contains methods for creating a vertex list and an adjacency private final int MAX_VERTS = 20;
matrix, and for adding vertices and edges to a Graph object: private Vertex vertexList[]; // array of vertices
private int adjMat[][]; // adjacency matrix
private int nVerts; // current number of vertices
// -------------------------------------------------------------
public Graph() // constructor
{
vertexList = new Vertex[MAX_VERTS];
// adjacency matrix
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
for(int j=0; j<MAX_VERTS; j++) // set adjacency
for(int k=0; k<MAX_VERTS; k++) // matrix to 0
adjMat[j][k] = 0;
} // end constructor

23 24

23 24

public void addVertex(char lab) // argument is label Exercise 1: Write a Graph methods
public void displayVertices() and public void displayEdges().
{ Demonstrate as follows:
vertexList[nVerts++] = new Vertex(lab);
Within the Graph class, vertices are identified
} public static void main(String[] args)
by their index number in vertexList. {
// ------------------------------------------------------------- Graph theGraph = new Graph();
public void addEdge(int start, int end) theGraph.addVertex('A'); // 0
theGraph.addVertex('B'); // 1
{
The adjacency matrix provides information theGraph.addVertex('C'); // 2
adjMat[start][end] = 1; that is local to a given vertex. Specifically, it theGraph.addVertex('D'); // 3
adjMat[end][start] = 1; tells you which vertices are connected by a theGraph.addVertex('E'); // 4
single edge to a given vertex. theGraph.addEdge(0, 1); // AB Vertices: ABCDE
} theGraph.addEdge(1, 2); // BC Edges:
theGraph.addEdge(0, 3); // AD A -- B
// ------------------------------------------------------------- A–D
theGraph.addEdge(3, 4); // DE
public void displayVertex(int v) System.out.print("Vertices: "); B–C
theGraph.displayVertices(); D -- E
{
System.out.println();
System.out.print(vertexList[v].label); System.out.println("Edges:");
} theGraph.displayEdges();
}
} // end class Graph
25

25 26

4
7/20/2024

Exercise 19.9 Exercise 19.10


Write a Graph method public void removeVertexEdges(int v) that removes all Write a Graph method public int vertexOutDegree(int v) that tells the out -
the Edges exiting a given vertex, by directly accessing the two -dimensional array. degree of a given vertex id (defined to be the number of Edges exiting the vertex) by
Demonstrate by: directly accessing the two - dimensional array.

System.out.println("\nRemoving Vertex 0 Edges:"); To test, add the following code to main():


theGraph.removeVertexEdges(0); theGraph.addEdge(3, 1); // DB
System.out.println(); theGraph.addEdge(3, 2); // DC
System.out.println("Edges:"); theGraph.addEdge(3, 4); // DE
theGraph.displayEdges(); theGraph.addEdge(4, 3); // ED
theGraph.addEdge(2, 3); // CD
Removing Vertex 0 Edges:
Display the in and out degrees for virtex 3.
Removing Vertex “A” Edges:
Edges:
Exercise 19.11
B–C Write a Graph method public int vertexInDegree(int v) that tells the in -
D -- E
degree of a given vertex id (defined to be the number of Edges coming in to that vertex) by
directly accessing the two - dimensional array.
System.out.println("\nVertex 3 has out-degree:"+theGraph.vertexOutDegree(3));
System.out.println("\nVertex 3 has in-degree:"+theGraph.vertexInDegree(3));

Vertex 3:
D has out-degree:3
D has in-degree:2

27 28

Exercise 19.16* Exercise 19.17*


Write a Graph method public void tailLessThanHead() that tells how many Write a Graph method public Graph copy(): The executor creates and returns an
edges have a tail whose ID is a smaller number than its head's ID. exact duplicate of itself.

Exercise 19.18*
System.out.println("\nEdges with tails less than heads:"); Write a Graph method public Graph transpose(): The
theGraph.tailLessThanHead(); executor returns a new Graph object that has the same vertices but the reversed edges,
i.e., an edge from v to w is in one if and only if an edge from w to v is in the other.

Edges with tails less than heads:


B -- A
C -- B
D -- A
E -- D

29 30

Searches Depth-First Search


One of the most fundamental operations to perform on a graph is The depth-first search uses a stack to remember where it should
finding which vertices can be reached from a specified vertex. go when it reaches a dead end.
The numbers in this figure show the order in which the vertices
There are two common approaches to searching a graph: depth- are visited.
first search (DFS) and breadth-first search (BFS). Both will
eventually reach all connected vertices.

you pick a starting point—in this case, vertex A.


You then do three things: visit this vertex, push it onto a stack so
you can remember it, and mark it so you won’t visit it again.
31 33

31 33

5
7/20/2024

Next, you go to any vertex adjacent to A that hasn’t yet been Applying Rule 1 again leads you to H. At this point, however, you
visited. You visit B, mark it, and push it on the stack. need to do something else because there are no unvisited
You’re at B, and you do the same thing as before: go to an vertices adjacent to H.
adjacent vertex that hasn’t been visited. This leads you to F.

RULE 2
If you can’t follow Rule 1, then, if possible, pop a vertex off the
RULE 1 stack.
If possible, visit an adjacent unvisited vertex, mark it, and push it
on the stack.

34 35

34 35

Following this rule, you pop H off the stack, which brings you You visit D, G, and I, and then pop them all when you reach the
back to F. F has no unvisited adjacent vertices, so you pop it. dead end at I. Now you’re back to A. You visit E, and again
Same for B. Now only A is left on the stack. you’re back to A.

This time, however, A has no unvisited neighbors, so we pop it


A, however, does have unvisited adjacent vertices, so you visit off the stack.
the next one, C. But C is the end of the line again, so you pop RULE 3
it and you’re back to A.
If you can’t follow Rule 1 or Rule 2, you’re done.

36 37

36 37

DFS algorithm, visiting a node’s children before its siblings.

38 39

38 39

6
7/20/2024

Java Code
A key to the DFS algorithm is being able to find the vertices that
are unvisited and adjacent to a specified vertex. How do you
do this? The adjacency matrix is the key.
Ignore the arrow heads By going to the row for the specified vertex and stepping across
the columns, you can pick out the columns with a 1; the
column number is the number of an adjacent vertex. You can
then check whether this vertex is unvisited. If so, you’ve found
what you want—the next vertex to visit.
If no vertices on the row are simultaneously 1 (adjacent) and
also unvisited, there are no unvisited vertices adjacent to the
specified vertex.

40 42

40 42

Now we’re ready for the dfs() method of the Graph class.
It loops until the stack is empty.
// returns an unvisited vertex adjacent to v
public int getAdjUnvisitedVertex(int v) Within the loop, it does four things:
{ 1. It examines the vertex at the top of the stack, using peek().
for(int j=0; j<nVerts; j++) 2. It tries to find an unvisited neighbor of this vertex.
if(adjMat[v][j]==1 && vertexList[j].wasVisited==false) 3. If it doesn’t find one, it pops the stack.
return j; // return first such vertex 4. If it finds such a vertex, it visits that vertex and pushes it
return -1; // no such vertices onto the stack.
} // end getAdjUnvisitedVertex()

43 44

43 44

public void dfs() // depth-first search


{ // begin at vertex 0
Graph theGraph = new Graph();
vertexList[0].wasVisited = true; // mark it
theGraph.addVertex(‘A’); // 0 (start for dfs)
displayVertex(0); // display it
theGraph.addVertex(‘B’); // 1
theStack.push(0); // push it
theGraph.addVertex(‘C’); // 2
while( !theStack.isEmpty() ) // until stack empty,
theGraph.addVertex(‘D’); // 3
{
theGraph.addVertex(‘E’); // 4
// get an unvisited vertex adjacent to stack top
int v = getAdjUnvisitedVertex( theStack.peek() );
theGraph.addEdge(0, 1); // AB
if(v == -1) // if no such vertex,
theGraph.addEdge(1, 2); // BC
theStack.pop(); // pop a new one
theGraph.addEdge(0, 3); // AD
else // if it exists,
theGraph.addEdge(3, 4); // DE
{
vertexList[v].wasVisited = true; // mark it
System.out.print(“DFS Visits: “);
displayVertex(v); // display it
theGraph.dfs(); // depth-first search
theStack.push(v); // push it
System.out.println();
}
} // end while
// stack is empty, so we’re done DFS Visits: ABCDE
for(int j=0; j<nVerts; j++) // reset flags
vertexList[j].wasVisited = false;
45
Show DFS_App Code 46```````
} // end dfs

45 46

7
7/20/2024

Depth-First Search and Game Simulations


Depth-first searches are often used in simulations of games (and This can be represented by a graph with one node representing
game-like situations in the real world). your first move, which is connected to eight nodes
representing your opponent’s possible responses, each of
which is connected to seven nodes representing your
In a game of tic-tac-toe. If you go first, you can make one of nine responses, and so on.
possible moves. Your opponent can counter with one of eight
possible moves, and so on.
There are 9*8*7*6*5*4*3*2*1 paths in the nine graphs. This is 9
factorial (9!) or 362,880. In a game like chess where the
number of possible moves is much greater, even the most
powerful computers (like IBM’s “Deep Blue”) cannot “see” to
the end of the game. They can only follow a path to a certain
depth and then evaluate the board to see if it appears more
favorable than other choices.

49 50

49 50

Only some paths in a game tree lead to a successful conclusion. Breadth-First Search
For example, some lead to a win by your opponent. When you As we saw in the depth-first search, the algorithm acts as though
reach such an ending, you must back up, or backtrack, to a it wants to get as far away from the starting point as quickly as
previous node and try a different path. In this way you explore possible. In the breadth-first search, on the other hand, the
the tree until you find a path with a successful conclusion. algorithm likes to stay as close as possible to the starting
Then you make the first move along this path. point. It visits all the vertices adjacent to the starting vertex,
and only then goes further afield. This kind of search is
implemented using a queue instead of a stack.

Ignore the arrow heads

51 52

51 52

BCDE Thus, you first visit all the vertices adjacent to


A is the starting vertex, so you visit it and make it the current A, inserting
A is the starting vertex, so you visit it and each
makeoneitinto
thethecurrent
queue
as you visit it. Now you’ve visited A, B, C, D,
vertex. Then you follow these rules: vertex. Then you follow theseandrules:
E. At this point the queue (from front to
rear) contains BCDE.
RULE 1 RULE 1
Visit the next unvisited vertex (if there is one) that’s adjacent to Visit the next unvisited vertex (if there is one) that’s adjacent to
the current vertex, mark it, and insert it into the queue. the current vertex, mark it, and insert it into the queue.

53 54

53 54

8
7/20/2024

BCDE BCDE There are no more unvisited vertices adjacent


RULE 2 RULE 2 to A, so you remove B from the queue
and look for vertices adjacent to it.
If you can’t carry out Rule 1 because there are no more unvisited If you can’t carry out Rule 1 because there are no more unvisited
vertices, remove a vertex from the queue (if possible) and vertices, remove a vertex from the queue (if possible) and
make it the current vertex. make it the current vertex.

RULE 3 RULE 3
If you can’t carry out Rule 2 because the queue is empty, you’re If you can’t carry out Rule 2 because the queue is empty, you’re
done. done.

55 56

55 56

BCDEF There are no more unvisited vertices adjacent BCDEFG There are no more unvisited vertices adjacent
RULE 2 to A, so you remove B from the queue RULE 2 to A, so you remove B from the queue
and look for vertices adjacent to it. and look for vertices adjacent to it.
If you can’t carry out Rule 1 because there are no more unvisited If you can’t carry out Rule 1 because there are no more unvisited
Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There
are no more unvisited vertices adjacent to B, are no more unvisited vertices adjacent to B,
make it the current vertex. so you remove C from the queue. make it the current vertex. so you remove C from the queue.

C has no adjacent unvisited vertices, so you


RULE 3 RULE 3 remove D and visit G.
If you can’t carry out Rule 2 because the queue is empty, you’re If you can’t carry out Rule 2 because the queue is empty, you’re
done. done.

57 58

57 58

BCDEFG There are no more unvisited vertices adjacent BCDEFGH There are no more unvisited vertices adjacent
RULE 2 to A, so you remove B from the queue RULE 2 to A, so you remove B from the queue
and look for vertices adjacent to it. and look for vertices adjacent to it.
If you can’t carry out Rule 1 because there are no more unvisited If you can’t carry out Rule 1 because there are no more unvisited
Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There
are no more unvisited vertices adjacent to B, are no more unvisited vertices adjacent to B,
make it the current vertex. so you remove C from the queue. make it the current vertex. so you remove C from the queue.

C has no adjacent unvisited vertices, so you C has no adjacent unvisited vertices, so you
RULE 3 remove D and visit G. RULE 3 remove D and visit G.
If you can’t carry out Rule 2 because the queue is empty, you’re If you can’t carry out Rule 2 because the queue is empty, you’re
D has no more adjacent unvisited vertices, so D has no more adjacent unvisited vertices, so
done. you remove E. done. you remove E.

Now the queue is FG. You remove F and visit H,


59 60
and then you remove G and visit I.

59 60

9
7/20/2024

BCDEFGHI There are no more unvisited vertices adjacent BCDEFGHI There are no more unvisited vertices adjacent
RULE 2 to A, so you remove B from the queue RULE 2 to A, so you remove B from the queue
and look for vertices adjacent to it. and look for vertices adjacent to it.
If you can’t carry out Rule 1 because there are no more unvisited If you can’t carry out Rule 1 because there are no more unvisited
Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There
are no more unvisited vertices adjacent to B, are no more unvisited vertices adjacent to B,
make it the current vertex. so you remove C from the queue. make it the current vertex. so you remove C from the queue.

C has no adjacent unvisited vertices, so you C has no adjacent unvisited vertices, so you
RULE 3 remove D and visit G. RULE 3 remove D and visit G.
If you can’t carry out Rule 2 because the queue is empty, you’re If you can’t carry out Rule 2 because the queue is empty, you’re
D has no more adjacent unvisited vertices, so D has no more adjacent unvisited vertices, so
done. you remove E. done. you remove E.

Now the queue is HI, but when you’ve Now the queue is HI, but when you’ve
removed each of these and found no removed each of these and found no
adjacent unvisited vertices, the queue is Now the queue is FG. You remove F and visit H, adjacent unvisited vertices, the queue is Now the queue is FG. You remove F and visit H,
empty, so you’re done. and then you remove G and visit I. 61 empty, so you’re done. and then you remove G and visit I. 62

61 62

BCDEFGHI There are no more unvisited vertices adjacent


RULE 2 to A, so you remove B from the queue
and look for vertices adjacent to it.
If you can’t carry out Rule 1 because there are no more unvisited
Youthe
vertices, remove a vertex from find queue
F, so you (if
insert it in the queue.
possible) and There
are no more unvisited vertices adjacent to B,
make it the current vertex. so you remove C from the queue.

C has no adjacent unvisited vertices, so you


RULE 3 remove D and visit G.
If you can’t carry out Rule 2 because the queue is empty, you’re
D has no more adjacent unvisited vertices, so
done. you remove E.

At each moment, the queue contains the


vertices that have been visited but whose
Now the queue is HI, but when you’ve neighbors have not yet been fully explored.
removed each of these and found no
adjacent unvisited vertices, the queue is Now the queue is FG. You remove F and visit H,
empty, so you’re done. 63 64
and then you remove G and visit I.

63 64

For BFS algorithm, visiting a node’s siblings before its children,


while in DFS algorithm, visiting a node’s children before its
siblings

Ignore the arrow heads

traverses the tree or graph level-by-level, visiting the nodes of the tree above in the
order a b c d e f g h i j k.

65 66

65 66

10
7/20/2024

2
1 1
6 1
3 3 `
2 2
3
5
4 4
4
6 6
5 5

Breadth-First from 3 Depth-First from 3

67 69

67 69

public void bfs() // breadth-first search


Java Code { // begin at vertex 0
The bfs() method of the Graph class is similar to the dfs() vertexList[0].wasVisited = true; // mark it
method, except that it uses a queue instead of a stack and displayVertex(0); // display it
theQueue.insert(0); // insert at tail
features nested loops instead of a single loop.
int v2;
The outer loop waits for the queue to be empty, whereas the while( !theQueue.isEmpty() ) // until queue empty,
inner one looks in turn at each unvisited neighbor of the {
current vertex. int v1 = theQueue.remove(); // remove vertex at head
// until it has no unvisited neighbors
while( (v2=getAdjUnvisitedVertex(v1)) != -1 )
{ // get one,
vertexList[v2].wasVisited = true; // mark it
displayVertex(v2); // display it
theQueue.insert(v2); // insert it
} // end while(unvisited neighbors)
} // end while(queue not empty)
// queue is empty, so we’re done
for(int j=0; j<nVerts; j++) // reset flags
vertexList[j].wasVisited = false;
72 } // end bfs() 73

72 73

Graph theGraph = new Graph(); Consider the following graph. If there is ever a decision between
theGraph.addVertex(‘A’); // 0 (start for dfs) multiple neighbor nodes in the BFS or DFS algorithms, assume
theGraph.addVertex(‘B’); // 1 we always choose the letter closest to the beginning of the
theGraph.addVertex(‘C’); // 2 alphabet first.
theGraph.addVertex(‘D’); // 3
theGraph.addVertex(‘E’); // 4

theGraph.addEdge(0, 1); // AB
theGraph.addEdge(1, 2); // BC
theGraph.addEdge(0, 3); // AD
theGraph.addEdge(3, 4); // DE

System.out.print(“BFS Visits: “);


theGraph.bfs(); // depth-first search In what order will the nodes be visited using a Breadth First
System.out.println(); Search? In what order will the nodes be visited using a Depth
First Search?
BFS Visits: ABDCE
BFS: ABDCEGHF DFS: ABCEHFGD
Show BFS_App Code 74 77

74 77

11
7/20/2024

Consider the following graph. If there is ever a decision between The breadth-first search has an interesting property: It first finds
multiple neighbor nodes in the BFS or DFS algorithms, assume all the vertices that are one edge away from the starting point,
we always choose the letter closest to the beginning of the then all the vertices that are two edges away, and so on.
alphabet first.
This is useful if you’re trying to find the shortest path (least
segments) from the starting vertex to a given vertex. You start
a BFS, and when you find the specified vertex, you know the
path you’ve traced so far has the least segments to the node.

In what order will the nodes be visited using a Breadth First


Search? In what order will the nodes be visited using a Depth
First Search?
Start with node (b).

78 79

78 79

Topological Sorting Arranged this way, the graph is said to be topologically sorted.
Imagine that you make a list of all the courses necessary for Any course you must take before some other course occurs
your degree, using Figure 13.11 as your input data. You then before it in the list.
arrange the courses in the order you need to take them. Actually, many possible orderings would satisfy the course
Obtaining your degree is the last item on the list, which might prerequisites. You could take the English courses C and F
look like this: BAEDGCFH first, for example: CFBAEDGH

80 81

80 81

The idea behind the topological sorting algorithm is unusual but STEP 2
simple. Two steps are necessary: Delete this vertex from the graph, and insert its label at the
STEP 1 beginning of a list.
Find a vertex that has no successors
Steps 1 and 2 are repeated until all the vertices are gone. At this
The successors to a vertex are those vertices that are directly point, the list shows the vertices arranged in topological order.
“downstream” from it— that is, connected to it by an edge that
points in their direction. If there is an edge pointing from A to
B, then B is a successor to A. In Figure 13.11, the only vertex
with no successors is H.

82 83

82 83

12
7/20/2024

The GraphD Workshop Applet Sort topologically

The graph shown above has many valid topological sorts, including:
7, 5, 3, 11, 8, 2, 9, 10 (visual left-to-right, top-to-bottom)
3, 5, 7, 8, 11, 2, 9, 10 (smallest-numbered available vertex first)
5, 7, 3, 8, 11, 10, 9, 2 (fewest edges first)
7, 5, 11, 3, 10, 8, 9, 2 (largest-numbered
Wait !
available vertex first)
7, 5, 11, 2, 3, 8, 9, 10 (attempting top-to-bottom, left-to-right)
3, 7, 8, 5, 11, 10, 2, 9 (arbitrary)

wikipedia

84 85

84 85

Sort topologically A topological sort is performed by


doing a depth first search on a
directed acyclic graph. The
nodes are then popped off the
stack resulting in a topological
sort. Assume the graph below
was directed.
The graph shown above has many valid topological sorts, including:
7, 5, 3, 11, 8, 2, 9, 10 (visual left-to-right, top-to-bottom)
3, 5, 7, 8, 11, 2, 9, 10 (smallest-numbered available vertex first)
5, 7, 3, 8, 11, 10, 9, 2 (fewest edges first)
7, 5, 11, 3, 10, 8, 9, 2 (largest-numbered available vertex first)
7, 5, 11, 2, 3, 8, 9, 10 (attempting top-to-bottom, left-to-right)
3, 7, 8, 5, 11, 10, 2, 9 (arbitrary)

wikipedia

86 87

86 87

public void topo() // topological sort


{
Cycles and Trees int orig_nVerts = nVerts; // remember how many verts
One kind of graph the topological-sort algorithm cannot handle is while(nVerts > 0) // while vertices remain,
a graph with cycles. What’s a cycle? It’s a path that ends up {
where it started. In Figure 13.14 the path B-C-D-B forms a // get a vertex with no successors, or -1
cycle. (Notice that A-B-C-A is not a cycle because you can’t int currentVertex = noSuccessors();
go from C to A.) if(currentVertex == -1) // must be a cycle
{
System.out.println("ERROR: Graph has cycles");
return;
}
// insert vertex label in sorted array (start at end)
sortedArray[nVerts-1] = vertexList[currentVertex].label;
deleteVertex(currentVertex); // delete vertex
} // end while
// vertices all gone;
Insidedisplay sortedArray
the while loop, which continues until the number of vertices
System.out.print("Topologically sorted
is reduced to 0. Here order:
are the steps");
involved:
for(int j=0; j<orig_nVerts; j++)
1. Call noSuccessors() to find any vertex with no successors.
2. If such
System.out.print( a vertex is found,
sortedArray[j] ); put the vertex label at the end of
sortedArray[] and delete the vertex from graph.
System.out.println("");
88
} // end topo 3. If an appropriate vertex isn’t found, the graph must have a cycle.
89

88 89

13
7/20/2024

public static void main(String[] args)


public int noSuccessors() // returns vert with no successors {
{ // (or -1 if no such verts) Graph theGraph = new Graph();
boolean isEdge; // edge from row to column in adjMat theGraph.addVertex('A'); // 0
for(int row=0; row<nVerts; row++) // for each vertex, theGraph.addVertex('B'); // 1
{ theGraph.addVertex('C'); // 2
isEdge = false; // check edges theGraph.addVertex('D'); // 3
for(int col=0; col<nVerts; col++) theGraph.addVertex('E'); // 4
{ theGraph.addVertex('F'); // 5
if( adjMat[row][col] > 0 ) // if edge to theGraph.addVertex('G'); // 6
{ // another, theGraph.addVertex('H'); // 7
isEdge = true; theGraph.addEdge(0, 3); // AD
break; // this vertex theGraph.addEdge(0, 4); // AE
} OnlynoSuccessors()
The if an entire rowmethod
is founduses
//withthe
noadjacency
has a1ssuccessor
do we know
matrixwe
tohave
find aa theGraph.addEdge(1, 4); // BE
} vertex with no successors;
vertex with no successors. // in this try
case, its row number is returned.
another theGraph.addEdge(2, 5); // CF
if( !isEdge ) In the outer for loop, it goes down
// if notheedges,
rows, looking at each vertex. theGraph.addEdge(3, 6); // DG
return row;For each vertex, it scans across // thehas
columns in the inner for loop,
no successors theGraph.addEdge(4, 6); // EG
} looking for a 1. If it finds one, it knows that that vertex has a theGraph.addEdge(5, 7); // FH Topologically sorted order: BAEDGCFH
successor, because there’s an edge from that vertex to another one. theGraph.addEdge(6, 7); // GH
return -1; // no such vertex
When it finds a 1, it bails out of the inner loop so that
} // end noSuccessors() theGraph.topo(); // do the sort
the next vertex can be investigated.
} // end main() Show TOPO_App Code91
90

90 91

Directed Graphs In a program, the difference between a non-directed graph and a


A directed graph has edges that have a direction. When this is directed graph is that an edge in a directed graph has only one
the case, the graph is called a directed graph. In a directed entry in the adjacency matrix. Figure 13.12 shows a small
graph you can proceed only one way along an edge. directed graph; Table 13.5 shows its adjacency matrix.

Each edge is represented by a single 1. The row labels show where


the edge starts, and the column labels show where it ends.

92 93

92 93

For a directed graph, the method that adds an edge thus needs Connectivity in Directed Graphs
only a single statement, We’ve seen how in a non-directed graph you can find all the
vertices that are connected by doing a depth-first or breadth-
public void addEdge(int start, int end) // directed graph first search.
{ When we try to find all the connected vertices in a directed
adjMat[start][end] = 1; graph, things get more complicated. You can’t just start from a
} randomly selected vertex and expect to reach all the other
connected vertices.

94 95

94 95

14
7/20/2024

Consider the graph in Figure 13.15. If you start on A, you can get The Connectivity Table
to C but not to any of the other vertices. If you start on B, you You can easily modify the dfs.java program (Listing 13.1) to start
can’t get to D, and if you start on C, you can’t get anywhere. the search on each vertex in turn. For the graph of Figure
The meaningful question about connectivity is: What vertices 13.15 the output will look something like this:
can you reach if you start on a particular vertex? AC
BACE
C
DEC
EC
This is the connectivity table for the directed graph. The first
letter is the starting vertex and subsequent letters show the
vertices that can be reached (either directly or via other
vertices) from the starting vertex.

96 97

96 97

Warshall’s Algorithm Warshall’s Algorithm


In some applications it’s important to find out quickly whether You could examine the connectivity table, but then you would
one vertex is reachable from another vertex. Perhaps you need to look through all the entries on a given row, which
want to fly from Athens to Murmansk on Hubris Airlines and would take O(N) time (where N is the average number of
vertices reachable from a given vertex).
you don’t care how many intermediate stops you need to
make. Is this trip possible? AC
BACE
C
DEC
EC

It is possible to construct a table that will tell you instantly (that


is, in O(1) time) whether one vertex is reachable from another.
Such a table can be obtained by systematically modifying a
graph’s adjacency matrix. The graph represented by this
revised adjacency matrix is called the transitive closure of the
original graph.

98 99

98 99

Warshall’s Algorithm Warshall’s Algorithm


Table 13.6 shows the adjacency matrix for the graph of Figure
13.15.

Row A
We start with row A. There’s nothing in columns A and B, but there’s a 1
at column C, so we stop there.
Now the 1 at this location says there is a path from A to C. If we knew
there was a path from some vertex X to A, then we would know
We can use Warshall’s algorithm which is based on a there was a path from X to C.
simple idea: Where are the edges (if any) that end at A? They’re in column A. So we
If you can get from vertex L to vertex M, and you can get examine all the cells in column A. In Table 13.6 there’s only one 1 in
from M to N, then you can get from L to N. column A: at row B. It says there’s an edge from B to A. So we know
there’s an edge from B to A, and another (the one we started with)
from A to C. From this we infer that we can get from B to C in two
100
steps. 101

100 101

15
7/20/2024

Warshall’s Algorithm Warshall’s Algorithm

1 1

To record this result, we put a 1 at the intersection of row B and column Row C has no 1s at all, so we go to row D. Here we find an edge from
C. D to E. However, column D is empty, so there are no edges that end
on D.
Rows B, C, and D
We go to row B. The first cell, at column A, has a 1, indicating an edge Row E
from B to A. In row E we see there’s an edge from E to C. Looking in column E we
Are there any edges that end at B? We look in column B, but it’s empty, see the first entry is for the edge B to E, so with B to E and E to C
so we know that none of the 1s we find in row B will result in finding we infer there’s a path from B to C. However, it’s already been
longer paths because no edges end at B. discovered, as indicated by the 1 at that location.

102 103

102 103

Warshall’s Algorithm

There’s another 1 in column E, at row D. This edge from D to E plus the


one from E to C imply a path from D to C, so we insert a 1 in that
cell.

Warshall’s algorithm is now complete. We’ve added two 1s to the


adjacency matrix, which now shows which nodes are reachable
from another node in any number of steps. If we drew a graph based
on this new matrix, it would be the transitive closure of the graph in
Figure 13.15. Draw the graph of the transitive closure of R

104 105

104 105

Add method public void applyWarshal() to the Graph class.


public class Test_Warshal Test your code with this graph
{
Vertices:
public static void main(String[] args)
B ABCDE
{
Graph theGraph = new Graph();
Edges:
theGraph.addVertex('A'); // 0 ABCDE A->B
theGraph.addVertex('B'); // 1
C A 01110 B->C
theGraph.addVertex('C'); // 2 A
theGraph.addVertex('D'); // 3
B 00110 B->D
C 00010 C->D
theGraph.addVertex('E'); // 4
D 00000 E->B
theGraph.addEdge(0, 2); // AC
theGraph.addEdge(1, 4); // BE E 01110
After Warshal
theGraph.addEdge(1, 0); // BA
E D Edges:
theGraph.addEdge(4, 2); // EC
A->B
theGraph.addEdge(3, 4); // DE
After Warshal A->C
System.out.println("Vertices: ");
A->C A->D
theGraph.displayVertices();
B->A B->C
System.out.println();
B->C B->D
System.out.println("Edges:");
B->E C->D
theGraph.displayEdges();
D->C E->B
D->E E->C
theGraph.applyWarshal();
E->C E->D
System.out.println("After Warshall");
theGraph.displayEdges();
} // end main() 106 107
}

106 107

16
7/20/2024

Minimum Spanning Trees The number of edges E in a minimum spanning tree is always
Figure 13.10a shows five vertices with an excessive number of one less than the number of vertices V:
edges, while Figure 13.10b shows the same vertices with the E=V–1
minimum number of edges necessary to connect them. This The algorithm for creating the minimum spanning tree is almost
constitutes a minimum spanning tree (MST). identical to that used for searching. It can be based on either
the depth-first search or the breadth-first search. In this
example we’ll use the breadth-first search.

108 109

108 109

public void dfs() // depth-first search


{ // begin at vertex 0
Perhaps surprisingly, by executing the depth-first search and vertexList[0].wasVisited = true; // mark it
recording the edges you’ve traveled to make the search, you displayVertex(0); // display it
automatically create a minimum spanning tree. The only theStack.push(0); // push it
difference between the minimum spanning tree method mst(), while( !theStack.isEmpty() ) // until stack empty,
which we’ll see in a moment, and the depth-first search {
method dfs(), which we saw earlier, is that mst() must // get an unvisited vertex adjacent to stack top
somehow record the edges traveled. int v = getAdjUnvisitedVertex( theStack.peek() );
if(v == -1) // if no such vertex,
theStack.pop(); // pop a new one
else // if it exists,
{
vertexList[v].wasVisited = true; // mark it
displayVertex(v); // display it
theStack.push(v); // push it
}
} // end while
// stack is empty, so we’re done
for(int j=0; j<nVerts; j++) // reset flags
vertexList[j].wasVisited = false;
110 111
} // end dfs

110 111

// mst declarations public static void main(String[] args)


while( !theStack.isEmpty() ) // until stack empty {
{ // get stack top Graph theGraph = new Graph();
int currentVertex = theStack.peek(); theGraph.addVertex('A'); // 0 (start for mst)
// get next unvisited neighbor In the else statement, the current vertex and theGraph.addVertex('B'); // 1
its next unvisited neighbor are displayed.
int v = getAdjUnvisitedVertex(currentVertex); theGraph.addVertex('C'); // 2
if(v == -1) These two vertices define the edge
// if no more that the
neighbors theGraph.addVertex('D'); // 3
algorithm is currently traveling to get to a new
theStack.pop(); // pop it away theGraph.addVertex('E'); // 4
vertex, and it’s these edges that make up the
else minimum spanning // got a neighbor
tree. theGraph.addEdge(0, 1); // AB
{ theGraph.addEdge(0, 2); // AC
vertexList[v].wasVisited = true; // mark it theGraph.addEdge(0, 3); // AD
theStack.push(v); // push it theGraph.addEdge(0, 4); // AE
// display edge theGraph.addEdge(1, 2); // BC
displayVertex(currentVertex); // from currentV theGraph.addEdge(1, 3); // BD
displayVertex(v); // to v theGraph.addEdge(1, 4); // BE
System.out.print(“ “; theGraph.addEdge(2, 3); // CD Minimum spanning tree: AB BC CD DE
} theGraph.addEdge(2, 4); // CE
} // end while(stack not empty) theGraph.addEdge(3, 4); // DE
// stack is empty, so we’re done System.out.print("Minimum spanning tree: ");
for(int j=0; j<nVerts; j++) // reset flags theGraph.mst(); // minimum spanning tree
vertexList[j].wasVisited = false; System.out.println();
112
Show MST_App Code113
} // end mst() } // end main()

112 113

17
7/20/2024

Using Depth-First Ch 14 Weighted Graphs


When we include weight as a feature of a graph’s edges, some
interesting and complex questions arise. What is the minimum
spanning tree for a weighted graph? What is the shortest (or
cheapest) distance from one vertex to another? Such
questions have important applications in the real world.

114 115

114 115

Minimum Spanning Tree with Weighted Graphs An Example: Cable TV in the Jungle
When all edges are the same weight, it’s fairly straightforward— Suppose we want to install a cable television line that connects
as we saw earlier—for the algorithm to choose one to add to six towns. Five links will connect the six cities. The cost of
the minimum spanning tree. But when edges can have connecting each pair of cities varies, so we must pick the
different weights, some arithmetic is needed to choose the route carefully to minimize the overall cost.
right one.,

116 117

116 117

Figure 14.1 shows a weighted graph with six vertices,


How can we pick a route that minimizes the cost of installing the
representing the towns Ajo, Bordo, Colina, Danza, Erizo, and
cable system? The answer is to calculate a minimum
Flor. Each edge has a weight, shown by a number alongside
spanning tree. It will have five links (one fewer than the
the edge. Imagine that these numbers represent the cost, in
number of towns), it will connect all six towns, and it will
millions of dollars, of installing a cable link between two cities.
minimize the total cost of building these links.

118 120

118 120

18
7/20/2024

Send Out the Surveyors Starting in Ajo


With graphs, algorithms tend to start at some vertex and work You start in Ajo. Only two towns are reachable from Ajo: Bordo
outward, acquiring data about nearby vertices before finding and Danza. You send two surveyors, one to Bordo and one to
out about vertices farther away. Danza. Their job is to determine the cost of installing cable
along these routes.

You make a list:


• Ajo–Danza, $4 million
• Ajo–Bordo, $6 million

121 122

121 122

You pick the least expensive one. So you build the Ajo–Danza Building the Ajo–Bordo Link
link and install an office in Danza before you can send out After you’ve completed the Ajo–Danza link and built your office in
surveyors from that town to adjacent towns. Danza, you can send out surveyors from Danza to all the
towns reachable from there Bordo, Colina, and Erizo.

• Ajo–Danza, $4 million
• Ajo–Bordo, $6 million
• Danza–Bordo, $7 million
• Danza–Colina, $8 million
• Danza–Erizo, $12 million

Why isn’t the Ajo–Danza link still on the list? Because you’ve
already installed the cable there; there’s no point giving any
further consideration to this link.

123 124

123 124

RULE Building the Bordo–Erizo Link


From the list, always pick the cheapest edge. You already know the costs from Danza to Colina and Erizo, but
you don’t know the costs from Bordo. So from Bordo you send
Here the cheapest edge is Ajo–Bordo, so you install a cable link out surveyors to Colina and Erizo. Here’s the new list:
from Ajo to Bordo, and build an office in Bordo.
• Danza–Bordo, $7 million
• Ajo–Bordo, $6 million • Bordo–Erizo, $7 million
• Danza–Bordo, $7 million • Danza–Colina, $8 million
• Danza–Colina, $8 million • Bordo–Colina, $10 million
• Danza–Erizo, $12 million • Danza–Erizo, $12 million

The Danza–Bordo link was on the previous list but is not on this
one because the two towns are already connected.
125 126

125 126

19
7/20/2024

• Bordo–Erizo, $7 million
Building the Erizo–Colina Link
• Danza–Colina, $8 million
From Erizo the surveyors report back costs of 5 million dollars to
• Bordo–Colina, $10 million
Colina and 7 to Flor.
• Danza–Erizo, $12 million
Your new list is
• Erizo–Colina, $5 million
From this list we can see that the cheapest route is Bordo–Erizo,
• Erizo–Flor, $7 million
at 7 million dollars. You send out the crew to install this cable
link, and you build an office in Erizo • Danza–Colina, $8 million
• Bordo–Colina, $10 million

The cheapest of these links is Erizo–Colina, so you build this link


and install an office in Colina.

127 128

127 128

And, Finally, the Colina–Flor Link The GraphW Workshop Applet


The choices are narrowing. After you remove already-linked
towns, your list now shows only
• Colina–Flor, $6 million
• Erizo–Flor, $7 million

You install the last link of cable from Colina to Flor, build an office
in Flor, and you’re done. You know you’re done because The applet should discover that the minimum spanning tree
there’s now an office in every town. consists of the edges AD, AB, BE, EC, and CF, for a total
edge weight of 28. The order in which the edges are specified
is unimportant. If you start at a different vertex, you will create
129 a tree with the same edges, but in a different order. 130

129 130

The Priority Queue Outline of the Algorithm


The key activity in carrying out the algorithm, as described in the Start with a vertex, and put it in the tree. Then repeatedly do the
cable TV example, was maintaining a list of the costs of links following:
between pairs of cities. We decided where to build the next 1. Find all the edges from the newest vertex to other vertices
link by selecting the minimum of these costs. that aren’t in the minimum spanning tree. Put these edges in
the priority queue.
A list in which we repeatedly select the minimum value suggests
a priority queue as an appropriate data structure. 2. Pick the edge with the lowest weight, and add this edge and
its destination vertex to the ms tree.

Repeat these steps until all the vertices are in the ms tree. At
that point, you’re done.

Java Code is skipped.

131 132

131 132

20
7/20/2024

Create a Minimum Spanning Tree for the shown Graph.

A A

B D B D
C C

E F E F

133 134

133 134

Wait !

135 136

135 136

Start from Ajo

137 139

137 139

21
7/20/2024

Start from Bordo


Find the minimum-cost spanning tree in the graph given in the
figure by using Prim’s algorithm, starting from the node 3.

140 141

140 141

Find the minimum-cost spanning tree in the graph given in the Find the minimum-cost spanning tree in the graph given in the
figure by using Kruskal’s algorithm. figure by using Prim’s algorithm, starting from the node 3.

142 143

142 143

The Shortest-Path Problem The Railroad Line


Perhaps the most commonly encountered problem associated This time we’re concerned with railroads rather than cable TV.
with weighted graphs is that of finding the shortest path We’re not going to build the railroad; it already exists. We just
between two given vertices. The solution to this problem is want to find the cheapest route from one city to another.
applicable to a wide variety of real-world situations.

144 145

144 145

22
7/20/2024

The railroad charges passengers a fixed fare to travel between The edges in Figure 14.6 are directed. They represent single-
any two towns. These fares are shown in Figure 14.6. That is, track railroad lines, on which (in the interest of safety) travel is
the fare from Ajo to Bordo is $50, from Bordo to Danza is $90, permitted in only one direction. For example, you can go
and so on. These rates are the same whether the ride directly from Ajo to Bordo, but not from Bordo to Ajo.
between two towns is part of a longer itinerary or not.

146 147

146 147

Although in this situation we’re interested in the cheapest fares, The shortest-path problem is this: For a given starting point and
the graph problem is nevertheless always referred to as the destination, what’s the cheapest route? In Figure 14.6, you
shortest-path problem (SPP). Here shortest doesn’t can see (with a little mental effort) that the cheapest route
necessarily mean shortest in terms of distance; it can also from Ajo to Erizo passes through Danza and Colina; it will cost
mean cheapest, fastest, or best route by some other you $140.
measure.

148 149

148 149

A Directed, Weighted Graph Dijkstra’s Algorithm


As we noted, our railroad has only single-track lines, so you can go The solution we’ll show for the shortest-path
in only one direction between any two cities. This corresponds to problem is called Dijkstra’s algorithm, after
a directed graph. Edsger Dijkstra a Dutch computer scientist, who
We could have portrayed the more realistic situation in which you first described it in 1959. This algorithm is based
can go either way between two cities for the same price; this on the adjacency matrix representation of a
would correspond to a non-directed graph. However, the shortest- graph. Somewhat surprisingly, it finds not only
path problem is similar in these cases, so for variety we’ll show the shortest path from one specified vertex to
how it looks in a directed graph. another, but also the shortest paths from the
specified vertex to all the other vertices.

150 151

150 151

23
7/20/2024

Agents and Train Rides The First Agent: In Ajo


You (and various agents you will hire) are going to play the role The stationmaster in Ajo can tell you is that it will cost $50 to ride
of the computer program carrying out Dijkstra’s algorithm. to Bordo and $80 to ride to Danza. You write this information
in your notebook, as shown in Table 14.2.
At each town, the stationmaster can tell you how much it will cost
to travel to the other towns that you can reach directly.

infinity

The table entries in parentheses


show the last town visited before
you arrive at the various
destinations.
152 153

152 153

RULE In the minimum spanning tree problem (the cable TV


Always send an agent to the town whose overall fare from the installation), you picked the least expensive single link (edge)
starting point (Ajo) is the cheapest. from the connected towns to an unconnected town.

Here, you pick the least expensive total route from Ajo to a town
with no agent.

154 155

154 155

The Second Agent: In Bordo Doing some quick arithmetic, you figure
The cheapest fare from Ajo is to Bordo, at $50. So you hire a it must be $50 plus $60, or $110 to
passerby and send him to Bordo, where he’ll be your agent. go from Ajo to Colina via Bordo, so
When he’s there, he calls you by telephone and tells you that you modify the entry for Colina. You
the Bordo stationmaster says it costs $60 to ride to Colina and also can see that, going via Bordo, it
$90 to Danza. must be $50 plus $90, or $140, from
Ajo to Danza. However—and this is
a key point—you already know it’s
only $80 going directly from Ajo to
Danza. You care only about the
cheapest route from Ajo, so you
ignore the more expensive route,
leaving this entry as it was.

156 157

156 157

24
7/20/2024

We’ll put a * next to Bordo (via Ajo) to show that there’s an agent The Third Agent: In Danza
in the town and that the cheapest fare to it is fixed. You hire another passerby and send her to Danza, with an $80
ticket. She reports that from Danza it’s $20 to Colina and $70
to Erizo. Now you can modify your entry for Colina.

Before, it was $110 from Ajo, going


via Bordo. Now you see you can
reach Colina for only $100, going
via Danza. Also, you now know a
fare from Ajo to the previously
unknown Erizo: it’s $150, via
Danza.

158
100 (via Danza) 150 (via 159
Danza)

158 159

Now you can calculate that, since Colina is $100 from Ajo (via
The Fourth Agent: In Colina
Danza), and Erizo is $40 from Colina, you can reduce the
Now the cheapest path to any town without an agent is the $100 minimum Ajo-to-Erizo fare from $150 (the Ajo–Danza–Erizo
trip from Ajo to Colina, going via Danza. Accordingly, you route) to $140 (the Ajo–Danza–Colina–Erizo route).
dispatch an agent over this route to Colina. He reports that it’s
$40 from there to Erizo.

140 (via Colina)

160 161

160 161

The Last Agent: In Erizo This narrative has demonstrated the essentials of Dijkstra’s
You dispatch an agent to Erizo, but she reports that there are no algorithm. The key points are
routes from Erizo to towns without agents. (There’s a route to • Each time you send an agent to a new town, you use the new
Bordo, but Bordo has an agent.) Table 14.6 shows the final information provided by that agent to revise your list of fares.
line in your notebook; all you’ve done is add a star to the Erizo Only the cheapest fare (that you know about) from the starting
entry to show that an agent is there. point to a given town is retained.
• You always send the new agent to the town that has the
cheapest path from the starting point (not the cheapest edge
from any town with an agent, as in the minimum spanning
tree).

162 163

162 163

25
7/20/2024

Consider the directed graph shown in the figure below. There are
multiple shortest path between vertices S and T. Which one
will be reported by Dijstra’s shortest path algorithm? Assume
that, in any iteration, the shortest path to a vertex v is updated
only when a strictly shorter path to v is discovered.
Using Dijstra’s shortest path algorithm, find the shortest path
from S to all other nodes showing the results after each step..

S A B C D E F G T
1 4 (via S) 3 (via S) inf 7 (via S) inf inf inf inf

164 165

164 165

S A B C D E F G T S A B C D E F G T
1 4 (via S) 3 (via S) inf 7 (via S) inf inf inf inf 1 4 (via S) 3 (via S) inf 7 (via S) inf inf inf inf
2 5 (via A) 8 (via D) 12 (via D) 10 (via D) 2 5 (via A) 8 (via D) 12 (via D) 10 (via D)
3 3 6 (via C)
4

166 167

166 167

S A B C D E F G T
1 4 (via S) 3 (via S) inf 7 (via S) inf inf inf inf A B C D E F G H I
2 5 (via A) 8 (via D) 12 (via D) 10 (via D)
3 6 (via C)
4 8 (via E)

168 169

168 169

26
7/20/2024

Homework : In the following graph, each vertex contains a letter that can Homework : In the following graph, each vertex contains a letter that can
be used to identify it. Each edge has a number next to it indicating its be used to identify it. Each edge has a number next to it indicating its
"length". Most edges are undirected; directed edges have an arrow on "length". Most edges are undirected; directed edges have an arrow on
them indicating their directionality. Calculate the shortest path from them indicating their directionality. Calculate the shortest path from
vertex a to vertex j using Dijkstra's algorithm. vertex a to vertex j using Dijkstra's algorithm.

a b c d e f g h i j a b c d e f g h i j
1 3(->a) 8(->a) 5(->a)
2 7(->d) 15(->c) 10(->b) 9(->d)
3 15(->f) 16(->f) 13(->g)
4 18(->h)

175 176

175 176

ShortestPath_Directed.java
ShortestPath.java
1 2 3

14

0 8 4

7 6 5
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8 A B D G I H F C E
A B D G I H F C E 1 4(->0) 8(->0)
1 4(->A) 8(->A) 2 +8 12(->1) +1 9(->7) +7 15(->7)
2 12(->B) 9(->C) 15(->C) 3 +2 11(->6)
3 19(->D) 11(->F) 14(->D) 4 +14 25(->5) +14
4 28(->G) 21(->5)
5 +7 19(->2) +2 14(->2)
184 185

184 185

Kruskal's algorithm and Prim's algorithm find a minimum Intractable Problems


spanning tree for a connected graph. Some algorithms have big O values that are so large that they
can be used only for relatively small values of N.
Dijkstra's algorithm finds the shortest paths from a given vertex
to all other vertices. Many real-world problems that require such algorithms simply
cannot be solved in a reasonable length of time. Such
problems are said to be intractable.

186 187

186 187

27
7/20/2024

The Traveling Salesman Problem


A Hamilton circuit is a path that uses every vertex of a graph
Suppose we have a graph in which every edge has a weight exactly once.
(representing its cost, time, or distance).
Path means that the starting and ending vertices are different;
Circuit means that they are the same.

The TSP is then to find a path that


• visits every vertex; and
• has total weight as low as possible.
189

188 189

Changing the starting vertex (or \reference vertex") does not We can also make a Hamilton circuit into its \mirror image"
change the Hamilton circuit, because the same edges are by reversing direction. The mirror image uses the same edges,
traversed in the same directions. but backwards, so it is not considered the same as the original
Hamilton circuit.

190 191

190 191

Example: Sabrina has the following list of errands:


▪ Pet store (the black cat needs a new litterbox) (P)
▪ Greenhouse (replenish supply of deadly nightshade) (G)
▪ Pick up black dress from cleaners (C)
▪ Drugstore (eye of newt, wing of bat, toothpaste) (D)
▪ Target (weekly special on cauldrons) (T)

In which order should she do these errands in order to minimize


the time spent on her broom?

197 198

197 198

28
7/20/2024

199 200

199 200

The number of vertices is N = 6, so. . .


. . . the number of Hamilton circuits is
5! = 5 x 4 x 3 x 2 x 1 = 120
Half of these are duplicates in reverse order, so there are
(n−1)!/2 unique circuits.

How about listing all possible circuits?

201 202

201 202

If your computer can compute one million Hamilton circuits per


second. . .
N = 6, 7, 8, 9: instantaneous
N = 10: about 1/3 second
N = 11: about 4 seconds
N = 12: about 40 seconds
N = 13: about 8 minutes
What we have just done is the Brute-Force Algorithm
N = 14: nearly 2 hours
• Make a list of all possible Hamilton circuits
N = 15: a little over a day
• Calculate the weight of each Hamilton circuit by adding up the
N = 20: over a million years
weights of its edges.
• Choose the Hamilton circuit with the smallest total weight.

The Brute-Force Algorithm is optimal : it is guaranteed to find a


solution.
OTOH, the algorithm is inefficient: it has to look at all (N - 1)!
203 204
Hamilton circuits, and this can take a long time.

203 204

29
7/20/2024

Is there a better way to tackle the TSP? Idea: At each stage in your tour, choose the closest vertex
That is, is there an optimal algorithm that is also efficient? that you have not visited yet.

This is called the Nearest-Neighbor Algorithm.

205 206

205 206

Eventually, we end up with the Hamilton circuit


H, T, C, P, G, D, H.

•Weight of this circuit: 274


•Weight of an optimal circuit: 229
•Average weight of a circuit: 287.6
If Sabrina starts at home, the closest destination is the drugstore.

So, perhaps the Hamilton circuit ought to begin H,D.

The Brute-Force Algorithm is optimal but inefficient.


It is guaranteed to find a solution, but it may take an unreasonably long
time to do so.

The Nearest-Neighbor Algorithm is efficient but nonoptimal .

It is quick and easy, but does not always find the lowest-weight Hamilton
circuit.
www.math.ku.edu/~jmartin/
207 208

207 208

To avoid rental-car fees, he must finish the tour in the same


city he starts it in.

What route minimizes the total distance he has to travel?

i.e., in this weighted K16, which Hamilton circuit has the smallest
total weight?

Willy decides to visit every Australian city important enough to be


listed on some Wikipedia page. 209 210

209 210

30
7/20/2024

Willy could solve the problem by brute force: Idea:


At each stage in your tour, choose the closest vertex that you
• Make a list of all possible Hamilton circuits. have not visited yet.
• Calculate the weight of each Hamilton circuit by adding
• up the weights of its edges. This is called the Nearest-Neighbor Algorithm (NNA).
• Pick the Hamilton circuit with the smallest total weight.
The result:
BIG PROBLEM: The Nearest-Neighbor algorithm, using Sydney as the reference
There are 16 vertices, so there are vertex, yields the Hamilton circuit

(16 -1)! = 15! = 1,307,674,368,000


whose total weight is 21,049 km.
Hamilton circuits that each need to be checked.
A randomly chosen Hamilton circuit would have averaged
40,680 km, so this is pretty good.
211 212

211 212

Observation: Willy can use any city as the reference vertex!

That is, Willy can execute the Nearest-Neighbor Algorithm


sixteen times, using each city once as the reference vertex.

Then, he can pick the Hamilton circuit with the lowest total
weight of these sixteen.

This is called the Repetitive Nearest-Neighbor Algorithm


(RNNA)
.

21,049 km
But can Willy do better?
213 214

213 214

Apparently, using Alice Springs (AS) as the reference vertex


yields the best Hamilton circuit so far, namely

Remember: Willy can still start anywhere he wants!


For instance,

represents the same Hamilton circuit.

Apparently, using Alice Springs (AS) as the reference vertex yields the best
Hamilton circuit so far, namely
215 216

215 216

31
7/20/2024

Randomly chosen Hamilton circuit: 40,680 km


Hamilton circuit using NNA/Sydney: 21,049 km
Hamilton circuit using RNNA: 18,459 km

• In general, there's no way of knowing in advance which


reference vertex will yield the best result.
• This algorithm is still efficient, but . . .

Is it optimal? That is, Can Willy do even better?

217 218

217 218

32

You might also like