CH23 Weighted Graphs
CH23 Weighted Graphs
CHAPTER 23
Weighted Graphs and Applications
Objectives
213
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
23.1 Introduction
<key point>
A graph is a weighted graph if each edge is assigned with a
weight. Weighted graphs have many practical applications.
<end key point>
Seattle
2097 Boston
983
Chicago
1331 214
807
1003 New York
787
Denver
533
1267 1260
599
888
San Francisco 1015 Kansas City
381 1663
864
496
Los Angeles 1435 Atlanta
781
810
Dallas
661
239
Houston 1187
Miami
Figure 23.1
The graph models the distances among the cities.
The preceding chapter introduced the concept of graphs. You learned how
to represent edges using edge arrays, edge lists, adjacency matrices,
and adjacency lists, and how to model a graph using the Graph
interface, the AbstractGraph class, and the UnweightedGraph class. The
preceding chapter also introduced two important techniques for
traversing graphs: depth-first search and breadth-first search, and
applied traversal to solve practical problems. This chapter will
introduce weighted graphs. You will learn the algorithm for finding a
minimum spanning tree in §23.4 and the algorithm for finding shortest
paths in §23.5.
Pedagogical NOTE
<side remark: graph learning tool>
Before we introduce the algorithms and applications for
weighted graphs, it is helpful to get acquainted with
weighted graphs using an interactive tool from
www.cs.armstrong.edu/liang/animation/WeightedGraphLearnin
gTool.html, as shown in Figure 23.2. The tool allows you
to enter vertices, specify edges and their weights, view
214
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
the graph, and find a MST and all shortest paths from a
single source, as shown in Figure 23.2.
Figure 23.2
You can use the tool to create a weighted graph with mouse
gestures and show MST and shortest paths.
<key point>
Often it is desirable to use a priority queue to store weighted
edges.
<end key point>
There are two types of weighted graphs: vertex weighted and edge
weighted. In a vertex-weighted graph, each vertex is assigned a weight.
In an edge-weighted graph, each edge is assigned a weight. Of the two
types, edge-weighted graphs have more applications. This chapter
considers edge-weighted graphs.
215
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
vertex weight
Figure 23.3
Each edge is assigned a weight on an edge-weighted graph.
Assume that the graph has n vertices. You can use a two-dimensional n ×
n matrix, say weights, to represent the weights on edges. weights[i][j]
represents the weight on edge (i, j). If vertices i and j are not
connected, weights[i][j] is null. For example, the weights in the graph
in Figure 23.3a can be represented using an adjacency matrix as
follows:
adjacencyMatrix = [ 0 1 2 3 4
[None, 2, None, 8, None], 0 None 2 None 8 None
[2, None, 7, 3, None],
1 2 None 7 3 None
[None, 7, None, 4, 5],
2 None 7 None 4 5
[8, 3, 4, None, 6],
[None, None, 5, 6, None] 3 8 3 4 None 6
] 4 None None 5 6 None
<key point>
WeightedGraph extends AbstractGraph.
<end key point>
The preceding chapter designed the Graph class for modeling graphs. We
design WeightedGraph as a subclass of Graph, as shown in Figure 23.4.
217
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Graph
WeightedGraph
queues[i] is a heap that contains all the weighted edges
queues: list
adjacent to vertex i.
WeightedGraph(vertices: list, edges: list) Constructs a weighted graph with the specified vertices and
edges.
getQueueForWeightedEdges(edges ): list Creates a priority queue and returns it.
printWeightedEdges(): void Displays all edges and weights.
getWeightedEdges(): list Returns all weighted edges for each vertex in a p riority
queue.
clear(): void Removes all vertices and edges from the graph.
addVertex(v : V): void Adds a vertex to the graph.
addEdge(u: int, v: int, weight: d oub le): void Adds a weighted edge to the grap h.
getM inimumSpanningTree(): MST Returns a min imum spanning tree starting from vertex 0.
getM inimumSpanningTreeAt(index: int): MST Returns a min imum spanning tree starting from vertex v.
getShortestPath(index: int): ShortestPathTree Returns all single-source shortes t paths.
Figure 23.4
WeightedGraph extends Graph.
219
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
76 # All vertices are found?
77 while len(T) < numberOfVertices:
78 # Search for the vertex with the smallest edge
79 # adjacent to a vertex in T
80 v = -1
81 smallestWeight = MAX_VALUE;
82 for u in T:
83 while not queues[u].isEmpty() and \
84 queues[u].peek().v in T:
85 # Remove the edge from queues[u] if the adjacent
86 # vertex of u is already in T
87 queues[u].remove()
88
89 if queues[u].isEmpty():
90 continue # Consider the next vertex in T
91
92 # Current smallest weight on an edge adjacent to u
93 edge = queues[u].peek()
94 if edge.weight < smallestWeight:
95 v = edge.v
96 smallestWeight = edge.weight
97 # u is the parent for v
98 parent[v] = u
99
100 if v != -1:
101 T.append(v) # Add a new vertex to the tree
102 else:
103 # The tree is not connected, a partial MST is found
104 break
105
106 totalWeight += smallestWeight
107
108 return MST(startingIndex, parent, T,
109 totalWeight, self.vertices)
110
111 # Find single source shortest paths
112 def getShortestPath(self, sourceIndex):
113 # T stores the vertices whose path found so far
114 T = [sourceIndex]
115
116 numberOfVertices = len(self.vertices)
117
118 # parent[v] stores the previous vertex of v in the path
119 # The parent of source is set to -1
120 parent = numberOfVertices * [-1]
121
122 # costs[v] stores the cost of the path from v to the source
123 # Initial cost set to infinity
124 costs = numberOfVertices * [MAX_VALUE]
125 costs[sourceIndex] = 0 # Cost of source is 0
126
127 # Get a copy of queues
128 queues = deepClone(self.queues)
129
130 # Expand T
131 while len(T) < numberOfVertices:
132 v = -1 # Vertex to be determined
133 smallestCost = MAX_VALUE # Set to infinity
134 for u in T:
135 while (not queues[u].isEmpty() and
136 queues[u].peek().v in T):
137 # Remove the vertex in queue for u
220
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
138 queues[u].remove()
139
140 if queues[u].isEmpty():
141 # All vertices adjacent to u are in T
142 continue
143
144 e = queues[u].peek()
145 if costs[u] + e.weight < smallestCost:
146 v = e.v
147 smallestCost = costs[u] + e.weight
148 # now u is the parent for v
149 parent[v] = u
150
151 T.append(v) # Add a new vertex to T
152 costs[v] = smallestCost
153
154 # Create a ShortestPathTree
155 return ShortestPathTree(sourceIndex, parent, T, costs,
156 self.vertices)
157
158 # Clone queues
159 def deepClone(queues):
160 copiedQueues = []
161
162 for i in range(len(queues)):
163 copiedQueues.append(Heap())
164 for e in queues[i].getLst():
165 copiedQueues[i].add(e)
166
167 return copiedQueues
168
169 # MST is a subclass of Tree, defined in the preceding chapter
170 class MST(Tree):
171 def __init__(self, startingIndex, parent, T,
172 totalWeight, vertices):
173 Tree.__init__(self, startingIndex, parent, T, vertices)
174 # Total weight of all edges in the tree
175 self.totalWeight = totalWeight
176
177 def getTotalWeight(self):
178 return self.totalWeight
179
180 # ShortestPathTree is an inner class in WeightedGraph
181 class ShortestPathTree(Tree):
182 def __init__(self, sourceIndex, parent, T, costs, vertices):
183 Tree.__init__(self, sourceIndex, parent, T, vertices)
184 self.costs = costs
185
186 # Return the cost for a path from the root to vertex v
187 def getCost(self, v):
188 return self.costs[v]
189
190 # Print paths from all vertices to the source
191 def printAllPaths(self):
192 print("All shortest paths from "
193 + str(self.vertices[self.root]) + " are:")
194 for i in range(len(self.costs)):
195 self.printPath(i) # Print a path from i to the source
196 print("(cost: " + str(self.costs[i]) + ")") # Path cost
197
198 def getEdges(edges):
199 edgeList = []
221
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
200
201 for i in range(len(edges)):
202 u = edges[i][0]
203 v = edges[i][1]
204 # Insert an edge into the heap
205 edgeList.append([u, v])
206
207 return edgeList
Listing 23.3 gives a test program that creates a graph for the one in
Figure 23.1 and another graph for the one in Figure 23.3a.
<Output>
The number of vertices in graph1: 12
The vertex with index 1 is San Francisco
The index for Miami is 9
The edges for graph1:
Vertex 0: (0, 1, 807) (0, 3, 1331) (0, 5, 2097)
Vertex 1: (1, 2, 381) (1, 0, 807) (1, 3, 1267) Formatted: English (U.S.)
Vertex 2: (2, 1, 381) (2, 3, 1015) (2, 4, 1663) (2, 10, 1435)
Vertex 3: (3, 4, 599) (3, 5, 1003) (3, 1, 1267)
(3, 0, 1331) (3, 2, 1015)
Vertex 4: (4, 10, 496) (4, 8, 864) (4, 5, 533) (4, 2, 1663)
(4, 7, 1260) (4, 3, 599)
Vertex 5: (5, 4, 533) (5, 7, 787) (5, 3, 1003)
(5, 0, 2097) (5, 6, 983)
Vertex 6: (6, 7, 214) (6, 5, 983)
Vertex 7: (7, 6, 214) (7, 8, 888) (7, 5, 787) (7, 4, 1260)
Vertex 8: (8, 9, 661) (8, 10, 781) (8, 4, 864)
(8, 7, 888) (8, 11, 810)
Vertex 9: (9, 8, 661) (9, 11, 1187)
Vertex 10: (10, 11, 239) (10, 4, 496) (10, 8, 781) (10, 2, 1435)
Vertex 11: (11, 10, 239) (11, 9, 1187) (11, 8, 810)
The program creates the edges for graph2 for the graph in Figure 23.3a
in lines 37–45. Line 47 invokes the printWeightedEdges() method on
graph2 to display all edges in graph2.
<key point>
A minimum spanning tree of a graph is a spanning tree with the
minimum total weights.
<end key point>
A graph may have many spanning trees. Suppose that the edges are
weighted. A minimum spanning tree has the minimum total weights. For
example, the trees in Figures 23.3b, 23.3c, 23.3d are spanning trees
for the graph in Figure 23.5a. The trees in Figures 23.3c and 23.3d are
minimum spanning trees.
10 10
6 5 8
7 5
8 10
5 7 7 8 5 7 7 8
12
(a) (b)
6 6 5
5
7
5 7 8 5 7 7 8
(c) (d)
Figure 23.5
The tree in (c) and (d) are minimum spanning trees of the graph in (a).
Figure 23.6
Find a vertex u in T that connects a vertex v in V – T with the
smallest weight.
1. Add vertex 0 to T.
2. Add vertex 5 to T, since Edge(5, 0, 5) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7a.
225
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
3. Add vertex 1 to T, since Edge(1, 0, 6) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7b.
4. Add vertex 6 to T, since Edge(6, 1, 7) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7c.
5. Add vertex 2 to T, since Edge(2, 6, 5) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7d.
6. Add vertex 4 to T, since Edge(4, 6, 7) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7e.
7. Add vertex 3 to T, since Edge(3, 2, 8) has the smallest weight
among all edges incident to a vertex in T, as shown in Figure
23.7f.
1 10 2 1 10 2
6 5 8 6
7 7 5 8
0 8 6 10 3 0 8 6 10 3
5 7 7 8 5 7 7 8
5 12 4 5 12 4
(a) (b)
1 10 1 10 2
2
6 8
6 5 8
7 5 7
0 8 6 10 3 0 8 6 10 3
5 7 7 8 5 7 7 8
5 12 4 5 12 4
(c) (d)
1 10 2 1 10 2
6 5 8 6 5 8
7 7
0 8 6 10 3 0 8 6 10 3
5 7 7 8 5 7 7 8
5 12 4 5 12 4
(e) (f)
Figure 23.7
The adjacent vertices with the smallest weight are added successively
to T.
NOTE:
<Side Remark: unique tree?>
A minimum spanning tree is not unique. For example, both
(c) and (d) in Figure 23.7 are minimum spanning trees for
226
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
the graph in Figure 23.7a. However, if the weights are
distinct, the graph has a unique minimum spanning tree.
NOTE:
<Side Remark: connected and undirected>
Assume that the graph is connected and undirected. If a
graph is not connected or directed, the algorithm will
not work. You may modify the algorithm to find a spanning
forest for any undirected graph.
Tree
MST
totalWeight: int Total weight of the tree.
M ST(root: int, parent: list, searchOrder: list, Cons tructs an MST with the specified root, parent array,
totalWeight: int, vertices: lis t) searchOrder, total weight for the tree, and vertices.
getTotalWeight(): in t Returns the totalWeight of the tree.
Figure 23.8
The MST class extends the Tree class.
227
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
After a new vertex is added to T (line 101), totalWeight is updated
(line 106). Once all vertices are added to T, an instance of MST is
created (line 108). Note that the method will not work if the graph is
not connected. However, you can modify it to obtain a partial MST.
The MST class extends the Tree class (line 170). To create an instance
of MST, pass root, parent, T, totalWeight, and vertices (lines 108-
109). The data fields root, parent, searchOrder, vertices, are defined
in the Tree class, which is in the Graph module in the preceding
chapter.
Listing 23.5 gives a test program that displays minimum spanning trees
for the graph in Figure 23.1 and the graph in Figure 23.3a,
respectively.
<Output>
Total weight is 6513.0
Root is: Seattle
Edges: (Seattle, San Francisco) (San Francisco, Los Angeles)
(Los Angeles, Denver) (Denver, Kansas City) (Kansas City, Chicago)
(New York, Boston) (Chicago, New York) (Dallas, Atlanta)
(Atlanta, Miami) (Kansas City, Dallas) (Dallas, Houston)
229
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Seattle
2097 Boston
1 983
Chicago
1331 9 214
807 8
1003 New York
787
7
Denver
533
1267 1260
599
3 888
4
San Francisco 1015
Kansas City
381 1663
2 864
496
Los Angeles 1435 10 Atlanta
5 781
810
Dallas
6 661
239
Houston 1187 11
Miami
Figure 23.9
The edges in the minimum spanning tree for the cities are highlighted.
<check point>
23.1
Find a minimum spanning tree for the following graph.
1 10 2
5 7 8
7
0 2 6 10 3
5 7 7 8
5 2 4
23.2
Is the minimum spanning tree unique if all edges have different
weights?
23.3
If you use an adjacency matrix to represent weighted edges, what will
be the time complexity for Prim’s algorithm?
23.4
What happens to the getMinimumSpanningTree() method in WeightedGraph if
the graph is not connected? Verify your answer by writing a test
program that creates an unconnected graph and invokes the
getMinimumSpanningTree() method. How do you fix the problem by
obtaining a partial MST?
<end check point>
23.5 Finding Shortest Paths
<key point>
A shortest path between two vertices is the path with the minimum
total weights.
<end key point>
230
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Given a graph with nonnegative weights on the edges, a well-known
algorithm for finding a single-source shortest path was discovered by
Edsger Dijkstra, a Dutch computer scientist. Dijkstra’s algorithm uses
costs[v] to store the cost of the shortest path from vertex v to the
source vertex s. So costs[s] is 0. Initially assign infinity to
costs[v] to indicate that no path is found from v to s. Let V denote
all vertices in the graph and T denote the set of the vertices whose
costs have been found so far. Initially, the source vertex s is in T.
The algorithm repeatedly finds a vertex u in T and a vertex v in V – T
such that costs[u] + w(u, v) is the smallest, and moves v to T. Here
w(u, v) denotes the weight on edge (u, v).
T
v
s u
Figure 23.10
Find a vertex u in T that connects a vertex v in V – T with the
smallest costs[u] + w(u, v).
231
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
The algorithm starts by adding the source vertex s into T and sets
costs[s] to 0 (line 5). It then continuously adds a vertex (say v) from
V – T into T. v is the vertex that is adjacent to a vertex in T with
the smallest costs[u] + w(u, v). For example, there are five edges
connecting vertices in T and V – T, as shown in Figure 23.10; (u, v) is
the one with the smallest costs[u] + w(u, v). After v is added to T,
set costs[v] to costs[u] + w(u, v) (line 10).
1 10 3
costs
5 0
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 -1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.11
The algorithm will find all shortest paths from source vertex 1.
1 10 3
costs
5 0 5
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 -1 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.12
Now vertices 1 and 2 are in the set T.
232
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
1 10 3
costs
5 6 0 5
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 2 -1 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.13
Now vertices [1, 2, 0] are in the set T.
1 10 3
costs
5 6 0 5 9
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 2 -1 1 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.14
Now vertices [1, 2, 0, 6] are in the set T.
1 10 3
costs
5 6 0 5 10 9
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 2 -1 1 1 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.15
Now vertices [1, 2, 0, 6, 3] are in the set T.
233
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Now T contains [1, 2, 0, 6, 3]. Vertices 4 and 5 are adjacent to the
vertices in T, and vertex 5 has the path of smallest cost to source
vertex 1. So add 5 to T. costs[5] now becomes 10, as shown in Figure
23.16.
1 10 3
costs
5 6 0 5 10 10 9
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 2 -1 1 1 0 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.16
Now vertices [1, 2, 0, 6, 3, 5] are in the set T.
1 10 3
costs
5 6 0 5 10 15 10 9
9 5 8
4 0 1 2 3 4 5 6
8 6 8
2 parent
1 4 7 5 2 -1 1 1 5 0 1
0 1 2 3 4 5 6
0 4 5
(a) (b)
Figure 23.17
Now vertices [1, 2, 6, 0, 3, 5, 4] are in set T.
234
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Tree
ShortestPathTree
costs: list costs[v] stores the cost for the path from th e source to v.
ShortestPathTree(s ource: int, parent: list, Constructs a shortest path tree with the s pecified s ource,
searchOrder: list, cos ts: list, vertices) parent array, and costs array.
getCost(vertexInd ex: int): int Returns th e cost for the path from the source to the vertex.
printAllPaths (): void Dis plays all paths from the s ource.
Figure 23.18
WeightedGraph.ShortestPathTree extends AbstractGraph.Tree.
The method needs to remove the elements from the queues in order to
find the one with the smallest total cost. To keep the original queues
intact, queues are cloned in line 128.
After a new vertex is added to T (line 151), the cost of this vertex is
updated (line 152). Once all vertices are added to T, an instance of
ShortestPathTree is created (lines 155-156). Note that the method will
not work if the graph is not connected. However, you can modify it to
obtain the shortest paths to all connected vertices.
Listing 23.7 gives a test program that displays all shortest paths from
Chicago to all other cities in Figure 23.1 and all shortest paths from
vertex 3 to all vertices for the graph in Figure 23.1, respectively.
<Output>
All shortest paths from Chicago are:
A path from Chicago to Seattle: Chicago Seattle (cost: 2097)
A path from Chicago to San Francisco:
Chicago Denver San Francisco (cost: 2270)
A path from Chicago to Los Angeles:
Chicago Denver Los Angeles (cost: 2018)
A path from Chicago to Denver: Chicago Denver (cost: 1003)
A path from Chicago to Kansas City: Chicago Kansas City (cost: 533)
A path from Chicago to Chicago: Chicago (cost: 0)
A path from Chicago to Boston: Chicago Boston (cost: 983)
A path from Chicago to New York: Chicago New York (cost: 787)
A path from Chicago to Atlanta:
Chicago Kansas City Atlanta (cost: 1397)
A path from Chicago to Miami:
Chicago Kansas City Atlanta Miami (cost: 2058)
A path from Chicago to Dallas:
Chicago Kansas City Dallas (cost: 1029)
A path from Chicago to Houston:
Chicago Kansas City Dallas Houston (cost: 1268)
Seattle
10
2097 Boston
3
983
Chicago
1331 214
807 2
1003 New York
787
Denver
533
1267 4 1260
11
599
1 888
San Francisco 1015
Kansas City
381 1663
8 864
7
496
Los Angeles 1435 Atlanta
5 781
810
Dallas
6 661
239
Houston 1187
9
Miami
Figure 23.19
The shortest paths from Chicago to all other cities are highlighted.
<key point>
The weighted Nine Tail problem can be reduced to the weighted
shortest path problem.
<end key point>
Section 16.9 presented the nine tail problem and solved it using the
BFS algorithm. This section presents a variation of the problem and
solves it using the shortest-path algorithm.
The nine tail problem is to find the minimum number of the moves that
lead to all coins face down. Each move flips a head coin and its
neighbors. The weighted nine tail problem assigns the number of flips
as a weight on each move. For example, you can move from the coins in
Figure 23.20a to those in Figure 23.20b by flipping the first coin in
the first row and its two neighbors. So the weight for this move is 3.
H H H T T H
T T T H T T
H H H H H H
(a) (b)
Figure 23.20
238
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
The weight for each move is the number of flips for the move.
The weighted nine tail problem is to find the minimum number of flips
that lead to all coins face down. The problem can be reduced to finding
the shortest path from a starting node to the target node in an edge-
weighted graph. The graph has 512 nodes. Create an edge from node v to
u if there is a move from node u to node v. Assign the number of flips
to be the weight of the edge.
NineTailModel
tree: Tree A tree rooted at node 511.
NineTailModel() Constructs a model for the nine tail problem and obtains th e
tree.
getShortestPath(nodeIndex: int): list Returns a path from the specified node to the root. The path
returned consists of the node labels in a list.
getEdges (): list Returns an ed ge lis t for the graph.
getNode(index: int): list Returns a node consisting of nine characters of H’s and T’s.
getIndex(node: list): int Returns the index of the specified node.
getFlippedNode(n ode: list, position: Flips the node at the specified position and returns the index
int): int of the flipped node.
flip ACell(node: list, row: in t, colu mn: Flips the node at the specified row and column.
int): void
printNode(n od e: list): void Dis plays the node to the console.
WeightedNineTailModel
WeightedNineTailM od el() Constructs a m odel for the weighted nine tail problem
and obtains a ShortestPathTree rooted from the target
node.
getNumberOfFlipsFrom(u: int): int Return s the number of flips from node u to the target
node 511.
getNumberOfFlips(u: int, v: int): int Return s the number of different cells between the two
nodes.
getWeightedEdges(): list Creates and return all edges for the graph.
Figure 23.21
WeightedNineTailModel extends NineTailModel.
239
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Listing 23.8 WeightedNineTailModel.py
<Side Remark line 10: extends NineTailModel>
<Side Remark line 12: constructor>
<Side Remark line 16: create vertices>
<Side Remark line 17: create a graph>
<Side Remark line 20: get a tree>
<Side Remark line 22: number of flips at u>
<Side Remark line 23: total number of flips>
<Side Remark line 26: get weighted edges>
<Side Remark line 34: get adjacent node>
<Side Remark line 35: weight>
<Side Remark line 38: add an edge>
<Side Remark line 38: flips from u to v>
1 from WeightedGraph import WeightedGraph
2 from WeightedGraph import WeightedEdge
3 from NineTailModel import NineTailModel
4 from NineTailModel import NUMBER_OF_NODES
5 from NineTailModel import getIndex
6 from NineTailModel import getNode
7 from NineTailModel import printNode
8 from NineTailModel import getFlippedNode
9
10 class WeightedNineTailModel(NineTailModel):
11 # Construct a model
12 def __init__(self):
13 NineTailModel.__init__(self) # Invoke superclass constructor
14
15 # Create a graph
16 vertices = [x for x in range(NUMBER_OF_NODES)]
17 graph = WeightedGraph(vertices, getWeightedEdges());
18
19 # Obtain a BSF tree rooted at the target node
20 self.tree = graph.getShortestPath(511)
21
22 def getNumberOfFlipsFrom(self, u):
23 return self.tree.getCost(u)
24
25 # Create all edges for the graph
26 def getWeightedEdges():
27 # Store edges
28 edges = []
29
30 for u in range(NUMBER_OF_NODES):
31 for k in range(9):
32 node = getNode(u) # Get the node for vertex u
33 if node[k] == 'H':
34 v = getFlippedNode(node, k)
35 numberOfFlips = getNumberOfFlips(u, v)
36
37 # Add edge (v, u) for a legal move from node u to node v
38 edges.append([v, u, numberOfFlips])
39
40 return edges
41
42 def getNumberOfFlips(u, v):
43 node1 = getNode(u)
44 node2 = getNode(v)
45
46 count = 0 # Count the number of different cells
240
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
47 for i in range(len(node1)):
48 if node1[i] != node2[i]:
49 count += 1
50
51 return count
Listing 23.9 gives a program that prompts the user to enter an initial
node and displays the minimum number of flips to reach the target node.
<Output>
241
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Enter an initial nine coin H’s and T's: HHHTTTHHH
HHH
THT
TTT
TTT
TTT
TTT
<check point>
23.5
Trace Dijkstra’s algorithm for finding shortest paths from Boston to
all other cities in Figure 23.1.
23.6
Is the shortest path between two vertices unique if all edges have
different weights?
23.7
If you use an adjacency matrix to represent weighted edges, what would
be the time complexity for Dijkstra’s algorithm?
23.8
What happens to the getShortestPath() method in WeightedGraph if the
graph is not connected? Verify your answer by writing a test program
that creates an unconnected graph and invoke the getShortestPath()
method.
<end check point>
Key Terms
Dijkstra’s algorithm
edge-weighted graph
minimum spanning tree
Prim’s algorithm
shortest path
single-source shortest path
vertex-weighted graph
Chapter Summary
1. You can use adjacency matrices or priority queues to store
weighted edges.
242
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
2. A spanning tree of a graph is a subgraph that is a tree and
connects all vertices in the graph. You learned how to implement
Prim’s algorithm for finding a minimum spanning tree.
3. You learned how to implement Dijkstra’s algorithm for finding
shortest paths.
Multiple-Choice Questions
Programming Exercises
23.1*
(Kruskal’s algorithm) The text introduced Prim’s algorithm for finding
a minimum spanning tree. Kruskal’s algorithm is another
well-known algorithm for finding a minimum spanning tree.
The algorithm repeatedly finds a minimum-weight edge and
adds it to the tree if it does not cause a cycle. The
process ends when all vertices are in the tree. Design and
implement an algorithm for finding an MST using Kruskal’s
algorithm.
23.2*
(Implementing Prim’s algorithm using adjacency matrix) The text
implements Prim’s algorithm using priority queues on
adjacent edges. Implement the algorithm using adjacency
matrix for weighted graphs.
23.3*
(Implementing Dijkstra’s algorithm using adjacency matrix) The text
implements Dijkstra’s algorithm using priority queues on
adjacent edges. Implement the algorithm using adjacency
matrix for weighted graphs.
23.4*
(Modifying weight in the nine tail problem) In the text, we assign the
number of the flips as the weight for each move. Assuming that the
weight is three times of the number of flips, revise the program.
23.5*
(Prove or disprove) The conjecture is that both NineTailModel and
WeightedNineTailModel result in the same shortest path. Write a program
to prove or disprove it. (Hint: Let tree1 and tree2 denote the trees
rooted at node 511 obtained from NineTailModel and
WeightedNineTailModel, respectively. If the depth of a node u is the
same in tree1 and in tree2, the length of the path from u to the target
is the same.)
23.6**
(Weighted 4 × 4 16 tail model) The weighted nine tail problem in the
text uses a 3 × 3 matrix. Assume that you have 16 coins placed in a 4 ×
4 matrix. Create a new model class named WeightedTailModel16. Create an
instance of the model and save the object into a file named
Exercise23_6.dat.
23.7**
243
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
(Weighted 4 × 4 16 tail view) Listing 23.12, NineTailApp.py, presents a
view for the nine tail problem. Revise this program for the weighted 4
× 4 16 tail problem. Your program should read the model object created
from the preceding exercise.
23.8**
(Traveling salesman problem) The traveling salesman problem (TSP) is to
find a shortest round-trip route that visits each city exactly once and
then returns to the starting city. The problem is equivalent to finding
a shortest Hamiltonian cycle. Add the following method in the
WeightedGraph class:
23.9*
(Finding a minimum spanning tree) Write a program that reads a
connected graph from a file and displays its minimum spanning tree. The
first line in the file contains a number that indicates the number of
vertices (n). The vertices are labeled as 0, 1, ..., n-1. Each
subsequent line describes the edges in the form of u1, v1, w1 | u2, v2,
w2 | .... Each triplet in this form describes an edge and its weight.
Figure 23.22 shows an example of the file for the corresponding graph.
Note that we assume the graph is undirected. If the graph has an edge
(u, v), it also has an edge (v, u). Only one edge is represented in the
file. When you construct a graph, both edges need to be considered.
100 1
0
File
3 20
6
0, 1, 100 | 0, 2, 3
40
2 3 1, 3, 20
2, 3, 40 | 2, 4, 2
5
2 5 3, 4, 5 | 3, 5, 5
9 4, 5, 9
4 5
(a) (b)
Figure 23.22
The vertices and edges of a weighted graph can be stored in a
file.
Your program should prompt the user to enter the name of the file,
should read data from a file, create an instance g of WeightedGraph,
invoke g.printWeightedEdges() to display all edges, invoke
getMinimumSpanningTree() to obtain an instance tree of
WeightedGraph.MST, invoke tree.getTotalWeight() to display the weight
of the minimum spanning tree, and invoke tree.printTree() to display
the tree. Here is a sample run of the program:
<Output>
Enter a file name: c:\exercise\Exercise23_9.txt
The number of vertices is 6
Vertex 0: (0, 2, 3) (0, 1, 100)
Vertex 1: (1, 3, 20) (1, 0, 100)
Vertex 2: (2, 4, 2) (2, 3, 40) (2, 0, 3)
Vertex 3: (3, 4, 5) (3, 5, 5) (3, 1, 20) (3, 2, 40)
Vertex 4: (4, 2, 2) (4, 3, 5) (4, 5, 9)
Vertex 5: (5, 3, 5) (5, 4, 9)
Total weight is 35
244
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
Root is: 0
Edges: (3, 1) (0, 2) (4, 3) (2, 4) (3, 5)
<End Output>
(Hint: Use new WeightedGraph(list, numberOfVertices) to create a graph,
where list contains a list of WeightedEdge objects. Use new
WeightedEdge(u, v, w) to create an edge. Read the first line to get the
number of vertices. Read each subsequent line into a string s and use
s.split("[\\|]") to extract the triplets. For each triplet,
triplet.split("[,]") to extract vertices and weight.)
23.10*
(Creating a file for a graph) Modify Listing 23.3,
TestWeightedGraph.py, to create a file for representing graph1. The
file format is described in Exercise 23.9. Create the file from the
array defined in lines 7-24 in Listing 23.3. The number of vertices for
the graph is 12, which will be stored in the first line of the file. An
edge (u, v) is stored if u < v. The contents of the file should be as
follows:
12
0, 1, 807 | 0, 3, 1331 | 0, 5, 2097
1, 2, 381 | 1, 3, 1267
2, 3, 1015 | 2, 4, 1663 | 2, 10, 1435
3, 4, 599 | 3, 5, 1003
4, 5, 533 | 4, 7, 1260 | 4, 8, 864 | 4, 10, 496
5, 6, 983 | 5, 7, 787
6, 7, 214
7, 8, 888
8, 9, 661 | 8, 10, 781 | 8, 11, 810
9, 11, 1187
10, 11, 239
23.11*
(Finding shortest paths) Write a program that reads a connected graph
from a file. The graph is stored in a file using the same format
specified in Exercise 23.9. Your program should prompt the user to
enter the name of the file, then two vertices, and should display the
shortest path between the two vertices. For example, for the graph in
Figure 23.21, a shortest path between 0 and 1 may be displayed as 0 2 4
3 1.
<Output>
Enter a file name: Exercise23_11.txt
Enter two vertices (integer indexes): 0 1
The number of vertices is 6
Vertex 0: (0, 2, 3) (0, 1, 100)
Vertex 1: (1, 3, 20) (1, 0, 100)
Vertex 2: (2, 4, 2) (2, 3, 40) (2, 0, 3)
Vertex 3: (3, 4, 5) (3, 5, 5) (3, 1, 20) (3, 2, 40)
Vertex 4: (4, 2, 2) (4, 3, 5) (4, 5, 9)
Vertex 5: (5, 3, 5) (5, 4, 9)
A path from 0 to 1: 0 2 4 3 1
<End Output>
23.12*
245
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.
(Displaying weighted graphs) Revise GraphView in Listing 23.6 to
display a weighted graph. Write a program that displays the graph in
Figure 23.1 as shown in Figure 23.23a.
(a) (b)
Figure 23.23
(a) Exercise 23.12 displays a weighted graph. (b) Exercise 23.14
displays an MST.
23.13*
(Displaying shortest paths) Revise GraphView in Listing 23.6 to display
a weighted graph and a shortest path between the two specified cities,
as shown in Figure 23.18. You need to add a data field path in
GraphView. If a path is set, the edges in the path are displayed in
red. If a city not in the map is entered, the program displays a dialog
box to alert the user.
23.14*
(Displaying a minimum spanning tree) Revise GraphView in Listing 23.6
to display a weighted graph and a minimum spanning tree for the graph
in Figure 23.1, as shown in Figure 23.23b. The edges in the MST are
shown in red.
23.15***
(Weighted graph visualization tool) Develop a GUI program as shown in
Figure 23.2, with the following requirements: (1) The radius of each
vertex is 20 pixels. (2) The user clicks the left-mouse button to place
a vertex centered at the mouse point provided that the mouse point is
not inside or too close to an existing vertex. (3) The user clicks the
right-mouse button inside an existing vertex to remove the vertex. (4)
The user presses a mouse button inside a vertex and drags to another
vertex and then releases the button to create an edge and distance
between the two vertices is also displayed. (5) The user drags a vertex
while pressing the CTRL key to move a vertex. (6) The vertices are
numbers starting from 0. When a vertex is removed, the vertices are
renumbered. (7) You can click the Show MST or Show All SP From the
Source button to display a MST or SP tree from a starting vertex. (8)
You can click the Show Shortest Path button to display the shortest
path between the two specified vertices.
246
© Copyright 2012 by Pearson Education, Inc. All Rights Reserved.