Educational Objectives: After completing this assignment, the student should be able to accomplish the following:
Operational Objectives: Design and implement class ALGraph and one or more graph algorithm classes from this list:
You may have teams of 1-3 people. Depending on the size of the team, you are required to do 1-3 of the algorithms along with the graph class. So, for example, a team of two people is required to do the ALGraph graph class and two of the algorithms.
Deliverables: Files:
graph.h # required for all fgraph.cpp # functionality test required for graph.h bfsurvey.h # required for a fbfsurvey.cpp # functionality test required for bfsurvey.h dfsurvey.h # required for b fdfsurvey.cpp # functionality test required for dfsurvey.h kruskal.h # required for c fkruskal.cpp # functionality test required for kruskal.h bfsiter.h # required for d fbfsiter.cpp # functionality test required for bfsiter.h dfsiter.h # required for e fdfsiter.cpp # functionality test required for dfsiter.h readme.txt # required for all makefile # builds all files in project
The official development | testing | assessment environment is gnu g++ on the linprog machines.
Each member of a team submits all team code
The team makup is listed in the file header documentation of each submitted file (see C++ Style link for standards)
File readme.txt explains how the software was developed, what responsibilities each team member had, how it was tested, and how it is expected to be operated.
Warning: Submit scripts do not work on the program and linprog servers. Use shell.cs.fsu.edu to submit projects. If you do not receive the second confirmation with the contents of your project, there has been a malfunction.
Class ALGraph implements the adjacency list representation of a graph whose vertices are assumed to be unsigned integers 0,1,...,n-1. The interface should conform to:
namespace fsu { template < typename N > class ALUGraph { public: typedef N Vertex; typedef xxxxx AdjIterator; void SetVrtxSize (N n); void AddEdge (Vertex from, Vertex to); size_t VrtxSize () const; size_t EdgeSize () const; size_t OutDegree (Vertex x) const; size_t InDegree (Vertex x) const; AdjIterator Begin (Vertex x) const; AdjIterator End (Vertex x) const; ALUGraph ( ); ALUGraph ( N n ); ... }; } // namespace fsu
where xxxxx is a type that you define. This is an iterator for the adjacency list, which could be fsu::TList<Vertex>::ConstIterator, std::list<Vertex>::const_iterator, or some other type. The directed graph API is exactly the same (but for the name of the class):
namespace fsu { template < typename N > class ALDGraph { public: typedef N Vertex; typedef xxxxx AdjIterator; void SetVrtxSize (N n); void AddEdge (Vertex from, Vertex to); size_t VrtxSize () const; size_t EdgeSize () const; size_t OutDegree (Vertex x) const; size_t InDegree (Vertex x) const; AdjIterator Begin (Vertex x) const; AdjIterator End (Vertex x) const; ALUGraph ( ); ALUGraph ( N n ); ... }; } // namespace fsu
Much of the implementation code for the undirected and directed cases is identical, so it can be profitable to derive one of these from the other. In the derived class, only AddEdge, EdgeSize, and InDegree require re-definition.
Begin(x) returns an AdjIterator which is a forward ConstIterator that iterates through the adjacency list of the vertex v. End(x) returns the end iterator of the adjacency list. So, the loop
for (typename GraphType::AdjIterator i = g.Begin(x); i != g.End(x); ++i) {/* do something at the vertex *i */}
encounters all of the vertices adjacent from v in the (directed or undirected) graph g.
The template argument is some unsigned integer type. We are using templates mainly as a convenience so that member functions will not be compiled (or even require implementation) if they are not called by client code.
Algorithms should operate on ALGraph objects via the interface defined above, so that another team's version of ALGraph can be substituted without modification.
Algorithms should be class templates (in line with the graph class template). See discussion of algorithm classes in the Graphs 1 Lecture Notes.
For ALGraph and each algorithm implemented by your team, a functionality test/demo client program should be created in the file fxxx.cpp, where xxx.h is the file holding the class being tested.
All graph and algorithm code should be tested thoroughly. Test code should be developed concurrently with the classes and a test plan should be agreed to and adhered to. The tests, test results, and general development plan should be documented in the text file readme.txt.
Your test programs should work with graphs defined in files using the format illustrated in the distributed data files. The file may begin with optional documentation - lines beginning with # are ignored. After the file documentation, there should be nothing but unsigned integer numbers in decimal notation. The first number is the number of vertices. Then the edges follow, one at a time, consisting of the from vertex followed by the to vertex. (Do not list an edge twice for an undirected graph.) For example:
# # file graph1.10.10 # # This is the graph G1 0 --- 1 2 --- 6 --- 7 # depicted to the right | | | # | | | # G1 has 10 vertices 3 --- 4 --- 5 --- 8 --- 9 # G1 has 10 edges Graph G1 10 0 1 0 3 2 5 2 6 3 4 4 5 5 8 6 7 7 9 8 9
This file represents the graph G1 from the Graphs 1 lecture notes. Note that each edge is listed only one time, and both ends of each edge are given. Several other graph files are distributed and should be used in your testing, along with any others you may deem appropriate. The format and order of the edge information should not matter to your test code, but it is nice for human readability. For example, the following file specifies the same undirected graph G1:
10 4 3 5 4 7 9 1 0 2 5 6 2 0 3 6 7 8 9 5 8
10 for the number of vertices, followed by the ten specified undirected edges. (Note this specifies a different directed graph, because some of the edges are listed in opposit direction.) This alternate representation is in file graph2.10.10.
The single command "make" should build all test and demo executables for your project, requiring ONLY the course library, the standard library, and your submitted files. You should test this by copying only your submit files to a separate directory and entering "make".
Even though our typical use of these classes will have the template argument N = size_t, it will be very useful in your implementation code to distinguish between type Vertex and type size_t and carefully cast between the two when the two types have different connotations. For example, if Vertex x and size_t i, then Begin((Vertex)i) and parent[(size_t)x].
Several graph files are distributed in LIB/proj4. Some of these are named graph.v.e and some are named are named dag.v.e, where v is the number of vertices and e the number of edges of the graph represented by the file. DO NOT rely on these suffixes in your programs, they are for human convenience only (and in some instances may not even be accurate). Those named dag are purported to be acyclic when interpreted as directed graphs, but will have cycles when interpreted as undirected graphs.
A thorough understandiing of the material on the Graphs 1 Lecture Notes will be helpful.
The following is output from a test of DFSSurvey run on G1 (undirected case):
linprog2> fdfsug.x graph1.10.10 Begin DFSurvey functionality test graph type: undirected adjacency list Load complete Input file: graph1.10.10 VrtxSize = 10 EdgeSize = 10 df survey data ============== vertex dtime ftime parent color ------ ----- ----- ------ ----- 0 0 19 NULL b 1 1 2 0 b 2 6 15 5 b 3 3 18 0 b 4 4 17 3 b 5 5 16 4 b 6 7 14 2 b 7 8 13 6 b 8 10 11 9 b 9 9 12 7 b Vertex discovery order: 0 1 3 4 5 2 6 7 9 8 Vertex finishing order: 1 8 9 7 6 2 5 4 3 0 End DFSurvey functionality test linprog2>
Note the table of survey data and the output of the vertices in preorder and postorder.
The following is output from a test of BFSSurvey run on G1 (directed case):
linprog2> fbfsdg.x graph1.10.10 Begin BFSurvey functionality test graph type: directed adjacency list Load complete Input file: graph1.10.10 VrtxSize = 10 EdgeSize = 10 df survey data ============== vertex distance dtime parent color ------ -------- ----- ------ ----- 0 0 0 NULL b 1 1 1 0 b 2 0 7 NULL b 3 1 2 0 b 4 2 3 3 b 5 3 4 4 b 6 1 8 2 b 7 2 9 6 b 8 4 5 5 b 9 5 6 8 b Vertex discovery order: 0 1 3 4 5 8 9 2 6 7 grouped by distance: [ ( 0 ) ( 1 3 ) ( 4 ) ( 5 ) ( 8 ) ( 9 ) ] [ ( 2 ) ( 6 ) ( 7 ) ] End BFSurvey functionality test linprog2>
Again the table shows the survey data. The vertex discovery order, grouped by distance from the search vertex, is also shown. (BFS discovers and finishes vertices in the same order.) The discovery order grouped by distance uses [ ] to delimit trees in the forest and ( ) to delimit vertices the same distance away from the root of the tree.
The discovery and finishing order are computed post-survey from the timestamps. (Discovery time was added to the usual BFS to facilitate this.) The discovery order "grouped by distance" output in fbfsurvey uses both distance and time. One could also output a Lisp-syntax record of the search forest for either survey.
Sample executables are available in LIB/area51. These show some elaborations such as digraphs, topological sort for digraphs, and output from the surveys that isn't direct. I added discovery time to BFSurvey, which is handy information to have, as illustrated by the post-survey computation of discovery order. Decode the names as follows:
fgraph.x # general test of Graph classes - can supply detailed log fdfsud.x # functionality test of DFSurvey - undirected graphs fdfsdg.x # functionality test of DFSurvey - directed graphs fbfsud.x # functionality test of BFSurvey - undirected graphs fbfsdg.x # functionality test of BFSurvey - directed graphs ftopsort.x # functionality test of TopSort - directed graphs only