CMPS 101: Programming Assignment 5 - Implementing Kruskal's Algorithm, Assignments of Computer Science

Instructions for a programming assignment in cmps 101 where students are required to implement kruskal's algorithm for finding a minimum weight spanning tree in a weighted undirected graph. The assignment involves creating a new function for adding undirected edges, sorting the edge array, and implementing a disjointset adt for the algorithm. Students are encouraged to use their graph module from a previous assignment as a starting point but are allowed to start from scratch.

Typology: Assignments

Pre 2010

Uploaded on 08/19/2009

koofers-user-w8v
koofers-user-w8v 🇺🇸

9 documents

1 / 4

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
CMPS 101
Abstract Data Types
Spring 2003
Programming Assignment 5
Due Wednesday June 4, 12:00 midnight
In the assignment you will extend your Graph module in C to implement Kruskal’s algorithm for finding
a minimum weight spanning tree in a weighted (undirected) graph. It is recommended that you use your
graph module from pa4 as a starting point for this project. However, since extensive changes to the
design will be necessary, you may choose to start from scratch. In any case it is not required that your
graph module in this project be backward compatible with pa4, or that the functionality from that project
be maintained.
One significant difference between this project and pa4 is that you will be working with undirected
graphs. Thus it will be necessary to create a function called AddEdge(u, v) (instead of AddDirectedEdge)
which establishes an undirected edge joining vertices u and v. AddEdge(u, v) will add v to the adjacency
list of u, and u to the adjacency list of v. Another difference is that each edge will posses a label as well
as a weight. It will therefore be worthwhile to include a private Edge struct (analogous to Node in List) in
your Graph module which encapsulates label, and weight, together with any other data associated with an
edge, such as it’s end vertices. The struct GraphStruct should then include a (dynamically allocated) array
of pointers to these Edges.
Kruskal’s algorithm requires that edges be processed in non-decreasing order by weight. Your Graph
module should therefore include a (private) function which will sort the Edge array. You may use any
sorting algorithm you like to implement this function. Kruskal’s algorithm also utilizes a disjoint set data
structure. Your project will implement this structure as a separate ADT module called DisjointSet. Your
DisjointSet module may use the linked list representation with weighted union heuristic, or the disjoint set
forest representation with union-by-rank and path compression heuristics. Design decisions such as these
should of course be carefully documented in your README file.
Your DisjointSet module will export the following functions.
/* Constructors-Destructors */
DisjointSetHndl NewDisjointSet(int n);
void FreeDisjointSet(DisjointSetHndl *pS);
/* Access functions */
int getNumElements(DisjointSetHndl S);
int getNumSets(DisjointSetHndl S);
int FindSet(DisjointSetHndl S, int x);
/* Manipulation procedures */
void Union(DisjointSetHndl S, int x, int y);
The elements of each member of a collection of disjoint sets will be integers. Function NewDisjointSet
returns a handle to a new DisjointSet object representing the collection {{1}, {2}, {3}, ..., { n}}. Thus
there is no need for a MakeSet function, since NewDisjointSet does essentially n MakeSet operations at
once. Function FreeDisjointSet frees all heap memory associated with a DisjointSet object, and sets its
DisjointSetHndl to Null. Functions getNumElements and getNumSets return the number of underlying
elements, and the number of sets in the collection, respectively. Function FindSet returns the
pf3
pf4

Partial preview of the text

Download CMPS 101: Programming Assignment 5 - Implementing Kruskal's Algorithm and more Assignments Computer Science in PDF only on Docsity!

CMPS 101

Abstract Data Types Spring 2003

Programming Assignment 5

Due Wednesday June 4, 12:00 midnight

In the assignment you will extend your Graph module in C to implement Kruskal’s algorithm for finding a minimum weight spanning tree in a weighted (undirected) graph. It is recommended that you use your graph module from pa4 as a starting point for this project. However, since extensive changes to the design will be necessary, you may choose to start from scratch. In any case it is not required that your graph module in this project be backward compatible with pa4, or that the functionality from that project be maintained. One significant difference between this project and pa4 is that you will be working with undirected graphs. Thus it will be necessary to create a function called AddEdge( u , v ) (instead of AddDirectedEdge) which establishes an undirected edge joining vertices u and v. AddEdge( u , v ) will add v to the adjacency list of u , and u to the adjacency list of v. Another difference is that each edge will posses a label as well as a weight. It will therefore be worthwhile to include a private Edge struct (analogous to Node in List) in your Graph module which encapsulates label, and weight, together with any other data associated with an edge, such as it’s end vertices. The struct GraphStruct should then include a (dynamically allocated) array of pointers to these Edges. Kruskal’s algorithm requires that edges be processed in non-decreasing order by weight. Your Graph module should therefore include a (private) function which will sort the Edge array. You may use any sorting algorithm you like to implement this function. Kruskal’s algorithm also utilizes a disjoint set data structure. Your project will implement this structure as a separate ADT module called DisjointSet. Your DisjointSet module may use the linked list representation with weighted union heuristic, or the disjoint set forest representation with union-by-rank and path compression heuristics. Design decisions such as these should of course be carefully documented in your README file. Your DisjointSet module will export the following functions. /* Constructors-Destructors */ DisjointSetHndl NewDisjointSet(int n); void FreeDisjointSet(DisjointSetHndl pS); / Access functions / int getNumElements(DisjointSetHndl S); int getNumSets(DisjointSetHndl S); int FindSet(DisjointSetHndl S, int x); / Manipulation procedures */ void Union(DisjointSetHndl S, int x, int y); The elements of each member of a collection of disjoint sets will be integers. Function NewDisjointSet returns a handle to a new DisjointSet object representing the collection {{1}, {2}, {3}, ..., { n }}. Thus there is no need for a MakeSet function, since NewDisjointSet does essentially n MakeSet operations at once. Function FreeDisjointSet frees all heap memory associated with a DisjointSet object, and sets its DisjointSetHndl to Null. Functions getNumElements and getNumSets return the number of underlying elements, and the number of sets in the collection, respectively. Function FindSet returns the

representative of the set containing the element x. It has the precondition 1  x^  n , where n is the number of elements in the collection. Function Union unites the sets containing x and y. It’s preconditions are 1  xn , 1  y^  n , and that the sets containing x and y are disjoint. If you choose the linked list representation, then Union is required to utilize the weighted union heuristic. If you choose the disjoint set forest representation, then Union must use the union-by-rank heuristic, and FindSet must use the path compression heuristic. In this case you must of course include a (private) function called Link with signature void Link(DisjointSetHndl S, int x, int y); which implements the Link function on p. 508 of the text. It is strongly recommended that your DisjointSet module export a function void printDisjointSet(DisjointSetHndl S); which prints out the internal state of a DisjointSet object. This function will be used for diagnostic purposes only. Your Graph module, which is the client of your DisjointSet module, will export the following functions. /* Constructors-Destructors / GraphHndl NewGraph(int n, int m); void FreeGraph(GraphHndl pG); / Access functions / int getOrder(GraphHndl G); int getSize(GraphHndl G); void getEdgeData(GraphHndl G, int e, int pu, int pv, double* pw); boolean isConnected(GraphHndl G); boolean sameComponent(GraphHndl G, int u, int v); /* Manipulation procedures / void addEdge(GraphHndl G, int u, int v, double w); / Other Functions / void Kruskal(GraphHndl G, ListHndl A); GraphHndl copyGraph(GraphHndl G); void printGraph(GraphHndl G, FILE out); Function NewGraph will return a handle to a new graph object containing n vertices and no edges. The parameter m determines the length of the Edge array, which initially contains only NULL pointers. FreeGraph frees all heap memory associated with a graph object and sets it’s GraphHndl argument to NULL. Function getOrder returns the number of vertices in the graph G , while getSize returns the number of edges. Function getEdgeData uses the output parameters pu, pv, and pw to return the end vertices and weight of the edge with label e. Function isConnected returns true if G is connected, and false otherwise. Function sameComponents returns true if vertices u and v belong to the same connected component of G , and false otherwise. It is recommended that your Graph module include a (private) function called ConnectedComponents with prototype void ConnectedComponents(GraphHndl G, DisjointSetHndl S); which implements the Connected-Components algorithm on p. 500 of the text. The resulting DisjointSet structure S can then be used by functions isConnected and sameComponents to determine their respective return values. As mentioned earlier, Function addEdge adds u to the adjacency list of v and v to the

You are required to submit the following files: README, Makefile, DisjointSet.c, DisjointSet.h, DisjointSetDriver.c, List.c, List.h, ListDriver.c, Graph.h, Graph.c, GraphDriver.c, MST.c. As usual README contains a catalog of submitted files and any special notes to the grader. Makefile should be capable of making the executables DisjointSetDriver, ListDriver, GraphDriver, MST, and should contain a clean utility which removes all object files. Let me say it once again: do not submit extra files, especially binary files. You may alter the following Makefile as you see fit:

Makefile for Graph ADT and related modules.

make makes MST

make GraphDriver makes GraphDriver

make ListDriver makes ListDriver

make DisjointSetDriver makes DisjointSetDriver

make clean removes all object and executable files

MST : MST.o Graph.o List.o DisjointSet.o gcc -o MST MST.o Graph.o List.o DisjointSet.o GraphDriver : GraphDriver.o Graph.o List.o DisjointSet.o gcc -o GraphDriver GraphDriver.o Graph.o List.o DisjointSet.o ListDriver : ListDriver.o List.o gcc -o ListDriver ListDriver.o List.o DisjointSetDriver : DisjointSetDriver.o DisjointSet.o gcc -o DisjointSetDriver DisjointSetDriver.o DisjointSet.o MST.o : MST.c Graph.h List.h gcc -c -ansi -Wall MST.c GraphDriver.o : GraphDriver.c Graph.h List.h gcc -c -ansi -Wall GraphDriver.c ListDriver.o : ListDriver.c List.h gcc -c -ansi -Wall ListDriver.c DisjointSetDriver.o : DisjointSetDriver.c DisjointSet.h gcc -c -ansi -Wall DisjointSetDriver.c Graph.o : Graph.c Graph.h List.h DisjointSet.h gcc -c -ansi -Wall Graph.c List.o : List.c List.h gcc -c -ansi -Wall List.c DisjointSet.o : DisjointSet.c DisjointSet.h gcc -c -ansi -Wall DisjointSet.c clean : rm MST GraphDriver ListDriver DisjointSetDriver MST.o GraphDriver.o ListDriver.o DisjointSetDriver.o Graph.o List.o DisjointSetDriver.o