CSE 326 - Winter 2003

Assignment 5

Searching For a-MAZE-ing Donuts

Assigned: Monday, March 3
Electronic submission due: Wednesday, March 12, 11:00am.
Hardcopy due: Wednesday, March 12, in class.

You may work in groups of one to three people.



Introduction

It is an incredibly important day for you at work at Minotaur, Inc. You've managed to arrive before any of your fellow co-workers, meaning you will have first dibs on some freshly-baked donuts! BUT - there is a problem. Your pointy-haired boss had the cubicles rearranged during the night, turning the whole office space into a complex and mistifying maze. Since you doubt you can find the true path to the donuts quickly, you decide to have a computer help you.

Graph search algorithms easily lend themselves to solving mazes. Each square of a maze can be viewed as a node in a graph. Two nodes are connected by an edge if the squares they represent are adjacent in the maze and a wall is not between them. You will implement several maze solvers that use different graph search techniques.

Assignment

You need to search for the donuts using breadth-first search (BFS) and Dijkstra's algorithms, which have been discussed in the lectures. You will read in weighted graphs, but BFS should ignore the weights.

The driver for your algorithms must be the MazeRunner class, which will:

  1. invoke breadth-first search as follows:
    1. load the maze from a file,
    2. find a path through the maze, and
    3. write detailed results into a file;

  2. invoke Dijkstra's algorithm following the same steps (the maze should be read from the same file, but the detailed results should be written into a different file, as explained next);

  3. print a one-line summary to the console.

MazeRunner must accept three command-line arguments that indicate the names of the input/output files as follows:

You may want to write a script to reduce the amount of typing during debugging (do NOT turn it in). For example:
   #!/bin/csh -f
   javac *.java && java MazeRunner ~/326/hw5/Inputs/$1.txt ~/326/hw5/Outputs/$1.bfs ~/326/hw5/Outputs/$1.dij

The detailed results to be written to the output files must consist of:

  1. the name of the input file (i.e., the first argument to MazeRunner),

  2. the printout of the maze, with the path to the donuts indicated,

  3. that same path as a sequence of room coordinates, starting with the entrance and ending with the exit from the maze (each line in the printout must contain the X then Y coordinates separated by a single space, with no other punctuation),

  4. if Dijkstra's algorithm was used, the final weights of each room, as computed by the algorithm (the weights in each row of the maze must be printed on a separate line, with a space preceeding each weight; rooms that have not been visited at all must be given the weight -1).

The summary to be printed to the console must consist of a single line containing the following items, separated by a single space:

  1. the length of the path found by BFS,
  2. the weight of the path found by Dijkstra's algorithm, and
  3. the name of the input file.

Hints. Your old friends, stacks and queues, might come in handy on this project. A search might involve visiting many nodes not on the solution path; you will need to find a means of extracting the path from the collection of nodes you visited.

Starter Code

We provide some starter code in Java:

Sample Mazes

We provide a collection of input mazes for you to test your code and experiment with. A description of a maze with unweighted (or, equivalently, unit-weight) doors (i.e., edges) starts with the dimensions of the maze. In the maze, '-' and '|' are used for walls, ' ' for rooms and doors (aka unblocked passages), '+' for the corners of the rooms, '*' for the entrance, and 'X'for the exit. Here is an example:
7 5
+-+-+-+-+-+-+-+
|*|   | | |   |
+ +-+ + + +-+ +
|   |   |     |
+ + + +-+ +-+ +
| |   |     | |
+ +-+-+ +-+-+ +
|       |     |
+-+ + +-+-+ +-+
|   |        X|
+-+-+-+-+-+-+-+
Unweighted mazes are here:   maze0.txt   maze1.txt   maze2.txt   maze3.txt   maze4.txt   maze5.txt   nocycles1.txt   nocycles2.txt   nocycles3.txt   bigmaze1.txt   bigmaze2.txt   bigmaze3.txt   bigmaze4.txt   bigmaze5.txt   bigmaze6.txt   bigmaze7.txt   bigmaze8.txt   bigmaze9.txt   bigmaze10.txt  

A weighted maze is specified similarly, except that the single-digit weights now replace the space symbols used indicate doors. The weighted versions of the above mazes are here:   wmaze0.txt   wmaze1.txt   wmaze2.txt   wmaze3.txt   wmaze4.txt   wmaze5.txt   wnocycles1.txt   wnocycles2.txt   wnocycles3.txt   wbigmaze1.txt   wbigmaze2.txt   wbigmaze3.txt   wbigmaze4.txt   wbigmaze5.txt   wbigmaze6.txt   wbigmaze7.txt   wbigmaze8.txt   wbigmaze9.txt   wbigmaze10.txt  

Here they are all in a single bundle: mazes.zip. (On UNIX, extract the contents with unzip mazes.zip.)

Questions

Compare the algorithms on the ten weighted mazes of the bigmaze variety and answer the following questions:
  1. Which of these mazes did BFS and Dijkstra's find different paths? Why did that happen?

  2. Draw the smallest and simplest maze that you can think of, where BFS and Dijkstra's would find different paths.

  3. We have discussed depth-first search (DFS) in the lectures. Do you think it will find the same path as BFS or the same path as Dijkstra's, given the same input maze? Explain your answer.
    Extra credit point. Sketch proofs or give counterexamples to support your answer. (If needed, make simple assumptions about how DFS is implemented.)

Extra Credit

Of course, there is always an opportunity to do something extra! This time, you may choose to write a program that creates mazes. Make it optionally produce mazes with cycles (say, if turning a wall into a door creates a cycle, allow this with a 5% chance). Make it optionally produce weighted graphs.

Deliverables

Turn in electronically all your source files. Follow the usual instructions. Include a Makefile for C++ projects.

In the class, turn in hardcopies of following:

Credits

This homework is an adaptation (and, of course, an improvement!) of a similar homework given earlier.   The EasyReader class comes from here.