Educational Objectives: After completing this assignment, the student should be able to accomplish the following:
Operational Objectives: Design, implement, and test various graph algorithms using the Graphs framework. Apply these algorithms to solve maze problems.
Deliverables: Three files with contents as follows:
filename contents -------- -------- graph_util.h CheckSymmetry, Path_BFS, Path_DFS (plus original contents of graph_util_partial.h) maze_util.h LoadMaze, Maze2Graph my_solved_maze.png graphic file of 100x120 maze and solution
The fsu Graph Framework consists of a number of classes, utility functions, and test harnesses. The following is a brief description of the files and their contents. These are discussed in considerably more detail in a companion guide.
FSU Graph Framework Filename Contents graph.h Class templates ALUGraph, ALDGraph. These implement adjacency lists representations for undirected and directed graphs, respectively. bfsurvey.h Class template BFSurvey. This class implements breadth-first survey as described in lecture notes.
Important engineering details are implemented that are not discussed in the class notes.dfsurvey.h Class template DFSurvey. This class implements depth-first survey as described in lecture notes.
Important engineering details are implemented that are not discussed in the class notes.graph_util.h A number of stand-alone functions and template functions assisting clients of the graph classes, including Load, ShowAL, Path_BFS, Path_DFS, and CheckSymmetry, along with several functions specifically supporting the test harnesses. survey_util.h Stand-alone functions primarily supporting the test harnesses for graph surveys. Includes Levelorder, Preorder, Postorder, and WriteData. topsort.h Function template TopSort implementing the Knuth topological sort algorithm. fgraph.cpp Client test harness for graph class templates.
Arguments: (1) graph file (req), (2) log file (opt)fbfsurvey.cpp Client test harness for BFSurvey class template. Can be configured for either undirected or directed graphs.
Arguments (all req): (1) graph file, (2) 'f'/'s' (full or single search), (3) start vertex number, (4) 1/0 (trace/no-trace).fdfsurvey.cpp Client test harness for DFSurvey class template. Can be configured for either undirected or directed graphs.
Arguments (all req): (1) graph file, (2) 'f'/'s' (full or single search), (3) start vertex number, (4) 1/0 (trace/no-trace).fpath.cpp Client test harness for Load, Path_BFS and Path_DFS. Reads graph file and displays BFS and DFS paths from x to y. Does both undirected and directed graphs.
Arguments (all req): (1) graph file, (2) from vertex, (3) to vertex.ftopsort.cpp Client test harness for TopSort function template.
Argument: (1) graph file (req)Maze Apps maze_util.h Functions supporting the study of mazes using the graph framework, including LoadMaze and Maze2Graph solvemaze.cpp Client test harness for Path_BFS, CheckSymmetry, and LoadMaze. Reads maze file, checks for consistency, solves the maze, and appends solution in maze file with ".bfs" extension.
Argument: (1) maze file (req).maze2graph.cpp Client test harness for Maze2Graph. Reads maze file, writes graph file containing directed graph model of maze. Graph file same as maze filename with ".dg" extension.
Arguments: (1) maze file (req), (2) 1/0 (directed/undirected) (optional - default is directed)printmaze.x Executable. Creates postscript file from maze file (with solution). Useful to print graphics and to include graphics in pdf documents.
Use with file redirect, and be sure to write to a file with ".ps" extension. (Written by Bret Whissel.)ps2png.sh Executable. Converts postscript file to png file for visual display. Assumes "$1.ps" and writes "$1.png".
Argument: (1) .ps filename without ".ps" extension (req)mazemaster.x Executable. Menu-driven maze analysis tool. Argument: command file (optional) Please note: It is very important to understand all of the code listed above in complete detail and as it fits into the theory discussed in the lecture notes. Mastery of this software is part of the assignment.
Copy all files from LIB/proj4/ into your project directory. These will include the test harnesses listed above along with a makefile and the submit script proj4submit.sh.
You may also want to copy some or all of the files from the graph framework, located in LIB/tcpp, since you will need to understand them in detail. If you copy these library files, be sure your code does not depend on these files being located in your project directory - that will not be true in your portfolio.
Create the deliverables listed above conforming to the requirements and specifications below.
Change permissions on the submit script to executable and submit the project by executing the script.
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.
The official development | testing | assessment environment is g++47 -std=c++11 -Wall -Wextra on the linprog machines. Code should compile without error or warning.
Algorithms should be fully compatibility with the fsu graph framework as released in the course library and should use that library whenever possible. Re-inventing the various features and components of the library is not appropriate.
Graph and Maze file specifications, as given in the course notes and previous assignments, should be adhered to.
Where appropriate, algorithms should be tested on both undirected and directed cases. Note that a number of examples are given, and the graph file format can be interpreted as both undirected and directed graph.
Path_BFS
Use the following header:
template < class G > bool Path_BFS (const G& g, typename G::Vertex x, typename G::Vertex y, fsu::List<typename G::Vertex>& p)
Applies BFSurvey to graph g, calculates BFS path from x to y and stores result in list p. Uses error stream to report errors, otherwise does no I/O. Returns true/false whether path exists.
Path_DFS
Use the following header:
template < class G > bool Path_DFS (const G& g, typename G::Vertex x, typename G::Vertex y, fsu::List<typename G::Vertex>& p)
Applies DFSurvey to graph g, calculates DFS path from x to y and stores result in list p. Uses error stream to report errors, otherwise does no I/O. Returns true/false whether path exists.
CheckSymmetry
Use the following header:
template < class G > bool CheckSymmetry (const G& g, bool verbose = 1)
Checks all edges in graph g for symmetric edge on the opposite direction. In other words, detects whether g is undirected. Reports vertices of edges with no corresponding reverse edge. Returns true/false whether symmetric.
LoadMaze
Use the following header:
template <typename N> bool LoadMaze (const char* mazefile, fsu::ALDGraph<N>& g, N& start, N& goal)
Opens and reads mazefile into g. Reads start and goal into start and goal, respectively. Returns true/false whether successful.
Maze2Graph
Use the following header:
bool Maze2Graph (const char* mazefile, bool directed = 1)
Opens mazefile and mazefile.dg [same name with ".dg" extension]. Reads mazefile and writes the digraph model into mazefile.dg (or, if directed is false, writes the ungraph model into mazefile.ug.) Ignores start and goal. Returns true/false whether successful.
The undirected case is the more natural model from the geometric point of view, where walls are unambiguously either up or down. The directed case is technically more useful when dealing with maze files, where walls codes might specify a wall up or down inconsistently between two cells sharing a common face.
my_solved_maze.png
This should be an example that you have processed using the tools described above:
We will also have a gallery in Blackboard to post these graphics.
A makefile is part of the distribution. You will need to un-comment one of the two ways to create ranmaze.x. Use the first method if possible.
The functionality for solvemaze.cpp is embodied in LoadMaze, CheckSymmetry, and Path_BFS, each of which you are supplying. The client itself is supplied and should not be modified, because we will use the same client in our testing.
Similarly, functionality for fpath.cpp and maze2graph.cpp is embodied in Path_DFS, Path_BFS, and Maze2Graph which you supply. These client tests are supplied and should not be modified.
The following is a 70x120 maze generated by ranmaze. Solution (red to green) obtained using Path_BFS in graph model.
If you have web space on ww2.cs.fsu.edu, you can set up a quick maze viewer as follows:
Put a script "mazegen.sh" in your space with contents:
#!/bin/sh ranmaze.x $1 $2 _TEMPMAZE cp _TEMPMAZE.1 maze$1x$2.1 solvemaze.x _TEMPMAZE.1 printmaze.x -h12 -w12 < _TEMPMAZE.1.bfs > _TEMPMAZE.ps pstopnm -stdout -yborder=0 -xborder=0 -portrait -xsize=1000 _TEMPMAZE.ps | pnmtopng > maze.png chmod 644 maze.png rm _TEMPMAZE* echo "maze graphic in maze.png"
Make a simple web page "viewmaze.html" with contents as follows:
<html> <head> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> <title>ViewMaze</title> <style type = "text/css"></style> </head> <body link="black" vlink="black" alink="#808080"> <br> <blockquote> <IMG SRC="maze.png" ALT="maze.png"><br> Maze generated by ranmaze. Solution obtained using Path_BFS in graph model. </body> </html>
Put copies of solvemaze.x and printmaze.x in the same directory.
Change permissions of *.x and *.sh to 700.
Change permissions of viewmaze.html to 644.
Then running "mazegen.sh $1 $2" followed by a refresh of the page will display the newly generated maze.
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.
Sample executables are created using the distributed makefile. 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 fdfs_ud.x # functionality test of DFSurvey - undirected graphs fdfs_dg.x # functionality test of DFSurvey - directed graphs fbfs_ud.x # functionality test of BFSurvey - undirected graphs fbfs_dg.x # functionality test of BFSurvey - directed graphs ftopsort.x # functionality test of TopSort - directed graphs only fpath.x # functionality test of Path_BFS and Path_DFS in both un- and di- graphs
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.