Assignment 13 -- Due Monday, December 6 (at the beginning of lab)
CS 4521 Fall Semester, 2010
25 Points

Topics: Minimum Spanning Trees and Single Source Shortest Paths

The assignment consists of two parts. In the first part you will hand-trace the algorithms of Kruskal and Prim to find minimum spanning trees. In the second part, you will implement Dijkstra's Algorithm to solve the single-source shortest paths problem.

Part I: Minimum Spanning Tree Exercises (10 points)

Consider the following undirected graph:
             5
     (B)----------(D)
      |\         / | \
      | \10   20/  |  \
      |  \     /   |   \
      |   \   /  12|   |
     3|    \ /     |   |
      |    (A)----(F)  |11
      |        2    \  |
      |             4\ |
      |               \|
     (C)--------------(E)
              15

  1. Trace the MST-Kruskal algorithm on this graph. Start by drawing the vertices only:
         (B)          (D)
    
    
    
    
    
               (A)    (F)
    
    
    
         (C)              (E)
    
    
    and show how the MST is grown by showing a snapshot of it after each edge is added.
    
    
  2. Trace the MST-Prim algorithm on this graph starting with root C by showing the priority queue after each iteration of the while loop. Also show the key value for each node. The initial queue should look like:
                            0 inf inf inf inf inf
                       Q: ( C  A   B   D   E   F )
    
    
    
    

Part II: Implementation of Dijkstra's Algorithm (15 points)

For this part, implement Dijkstra's algorithm (page 658), and run it on two graphs. As discussed on pages 661-662, the min-priority queue used in Dijkstra's algorithm may be implemented in three ways (each key value u.key) will always be equal to the distance estimate u.d):

Discussion:
Use numbers 1, 2, 3, 4, 5 instead of the letters s, t, x, y, z to identify the vertices. Also, the set S is only used to prove correctness of the algorithm -- so you don't have to include code for it. You can use a large number, say 1000 (I think 1 + the sum of the weights of all the edges is enough), instead of infinity in the initialization (I don't think there will be any arithmetic problems caused by using 1000 instead of INT_MAX or other fancy arithmetic). Also, you can use 0 for NIL, the intialization value for the pi field.

After initialization and at the end of each iteration of the while loop of Dijkstra's algorithm, your program should print out a list of all vertices, their d-values and their pi-values (it might also be useful for debugging to print out the priority queue). (Note: instead of the while loop, you can use a for-loop from 1 to n, though it would be easy to implement the empty() function for the priority queue - just keep track of the number of elements with "true" values in the inQ[] array.) Run this implementation on four different (G,w,source) combinations:

  1. The graph and weights G,w of Figure 24.2 page 648, with source s ( = 1 ) - you may get one of the solutions shown in (b) or (c) of Figure 24.2, or something different: graph 24.2, source s. This is essentially Exercise 24.3-1 on page 662.
  2. The graph and weights G,w of Figure 24.2 page 648, but with source z ( = 5 ): graph 24.2, source z.
  3. The graph and weights G,w of Figure 24.6 page 659, with source s ( = 1 ) - you may very well get the solution of Figure 24.6, or something different: graph 24.6, source s.
  4. The graph and weights G,w of Figure 24.6 page 659, but with source z ( = 5 ): graph 24.6, source z.
Also for each case, after the program run, draw the shortest-paths tree given by the predecessor graph. The data files have the number of vertices, n, and the source, source on the first line. Each subsequent line contains three values u v, and w, representing an edge, where the edge goes from vertex u to vertex v and has weight w.

Here is what the output from the first test should look like:

Built graph, n = 5

Run Dijkstra with source = 1

Iteration 1, Distances, d[1] = 0, d[2] = 3, d[3] = 1000, d[4] = 5, d[5] = 1000

Iteration 2, Distances, d[1] = 0, d[2] = 3, d[3] = 9, d[4] = 5, d[5] = 1000

Iteration 3, Distances, d[1] = 0, d[2] = 3, d[3] = 9, d[4] = 5, d[5] = 11

Iteration 4, Distances, d[1] = 0, d[2] = 3, d[3] = 9, d[4] = 5, d[5] = 11

Iteration 5, Distances, d[1] = 0, d[2] = 3, d[3] = 9, d[4] = 5, d[5] = 11

Final distances and predecessors:

Distances, d[1] = 0, d[2] = 3, d[3] = 9, d[4] = 5, d[5] = 11

Predecessors, pi[1] = 0, pi[2] = 1, pi[3] = 2, pi[4] = 1, pi[5] = 4
This corresponds to Figure 24.2 (b) on page 648. It is possible that changing the order of the adjacency lists could produce the shortest paths tree of Figure 24.2 (c).
Figure 24.6 (page 659) shows how the third test run should proceed.

Helpful code: Here is a .h file for a new Graph class graph.h and skeleton code for the Graph class implementation graph.cpp (you implement parts associated with Dijkstra's algorithm). Note: the Graph class has been designed to work with both weighted and unweighted graphs - weighted in this case. Here is a .h file for the "array" priority queue class PQueue pqueue.h and code for the PQueue class implementation pqueue.cpp. Here is a "driver" program that tests Dijkstra's algorithm: driver.cpp. Here is a "Makefile" that puts it all together: Makefile. When you download these files, be sure to remove the ".txt" suffixes (by moving them to the same file name without the ".txt").

What to turn in:


Page URL: http://www.d.umn.edu /~ddunham/cs4521f10/assignments/a13/assignment.html
Page Author: Doug Dunham
Last Modified: Monday, 29-Nov-2010 18:00:15 CST
Comments to: ddunham@d.umn.edu