Project OverviewFor this project you'll be creating a multi-threaded maze solver using some type(s) of thread pool(s) as part of your solution. Input will be a two-dimensional rectangular maze with at most one solution. This guarantees that there will not be any cycles/loops within any maze we test. This also means that a maze might not have a solution and you'll need to test every possible dead-end to know for sure. If a path through the maze exists, your maze solver will return that, otherwise it will return null. The ultimate goal is to solve the mazes while making optimal use of the resources available (this covers both processors and memory, so take care when using recursion and thread pools). The minimal goal is to use a threadpool with at least two threads to generate the correct answer without running out of memory. When grading in done beyond the public tests, your program will be evaluated in part based on the efficiency of your solution when compared to other single-threaded solutions. Getting StartedWe've put some starter files into your CVS repository. Included in this are five single-threaded example solvers, including a few different DFS approaches using the concept of "choice points" along the way. You might find that you'll need to set up the JVM so that it allows a large stack and heap sizes for very large mazes - that information is posted with the mazes. Maze Files
It will be CRITICALLY IMPORTANT to keep maze files OUTSIDE THE PROJECT FOLDER
when you are working on this since there is size limit for submissions and
anything in your project folder goes to CVS and I do not have room there
for lots of copies of maze files. I suggest you put a Mazes folder on your
desktop.
Single Threaded Solvers
STMazeSolverDFS
This is likely the best performing single-threaded solver, assuming a large
enough maze is provided.
Your Design Statement and Progress ReportBy 23:59:59 on Sunday, April 21st you will need to submit a document explaining the strategies you are using to approach the project goals. You should have read through the provided single-threaded solvers to get a sense of what your solution might need to use. Discuss which single-threaded solver you are starting from and how you plan to modify it, or explain how you will be coding a different approach. Your plans might change as you continue to work on the project, but by April 21st you need to be far along in reading the provided description and single-threaded code and into your design stage (and hopefully also into your implementation) to be able to discuss your plans and report on where things stand in terms of progress towards solving the maze using multiple threads. This statement should reflect how your design satisfies the criteria of usin gmore that one thread, particularly in your plan for managing your threads (Thread objects? Threadpools? other?) and how you plan to make sure that your concurrent solver is able to be faster than a single-threaded one. The document must be submitted as a PDF (if you don't have a virtual PDF printer on your Windows machine, CutePDF is available for free online - OS X has PDF printing built in).Running the solvers on a mazeTo run these above maze solvers and your own maze solver that you will put in the StudentMTMazeSolver class on the mazes provided or the ones you generate, use Eclipse and run Main class after modifying the filename currently hard-coded into the main method. There is also code there that you can un-comment to be able to run things from the command line, though you'll probably want to use Eclipse to recompile after each change to your code. The Main.main method will call the Main.solve method which will run all defined maze solvers on the same given maze file. Initial Code Layout
Several classes are provided in the CVS checkout:
Possible AlgorithmsThere are several algorithms that could produce good parallel solvers. One thing that is often true is that any given "choice point" (that is, a position from which multiple outgoing paths are possible) that does not lie on the solution path is likely to quickly lead to dead ends in all directions. As a result of this, statistically speaking, most of the time an exploration from a single choice point will quickly terminate (and thus run out of work) without having contributed positive information. This might suggest that if you want to make sure that your threads are each doing a fair amount of work, and some amount of useful work, it might be a good approach to have tasks consist of exploring several choice points, which should increase the amount of useful work per task. Also, note that there are no cycles/loops in the maze; this means that if you have two points A and B in the maze, and they aren't points such that going from the starting point to B goes through A, you know that they are completely independent of each other (consider this when thinking about the synchronization of any data structures you use). It may help to think of the maze as a tree structure, where the root is the starting point and only one of the leaves is an end point. One approach could be to perform a depth-first exploration until there are several unexplored paths on the stack you create in that algorithm, group these together and hand them off to a thread as a task. Of course you would want to make sure you group enough of them together so that the thread has a good amount of work to do given the overhead. You can also consider divide-and-conquer strategies. For example, each task could return a path from the current position to the end of the maze. You'd need to think about when to spawn off new tasks, then wait for them to complete; if any of them return a path, then the current node is added to that solution path and it is returned. We want you to use thread pools in some way. You get to choose what type of thread pool and how to use it to try to reduce the amount of overhead. Remember that if a task is waiting while in the pool, that is denying access to that thread to any other scheduled tasks queued up in the pool. One approach that has been shown to help in problems where there are two endpoints that you want to connect is to simultaneously work in from the each endpoint, hoping to meet in the middle. Of course, if things don't meet in the middle, you'll only disover that by exhaustion. Whatever approach(es) you explore, make sure that you have a way to limit the number of threads used by the algorithm since if too many threads are spawned, the overhead of thread management can erase the benefits given by the concurrent processing. Also, you could end up exhausting memory resources and crashing! Java allows you to find out how many processors are available by calling the method Runtime.getRuntime().availableProcessors(). Grading
TestingYou can use Linuxlab to test your program if your own machine does not have at least two processors (most of those machines do and you can have your program print out the number to check to see whether the machine you are using does. What to turn in...Every file you submit should have your name and UID. To enforce academic integrity, Code will be checked for similarity to other submissions. Each student should make his or her own individual submission. Use Eclipse to submit your project. Due to the non-deterministic nature of multi-threaded code, a portion of your project grade will come from manual inspection of your code, and since there are many approaches, our understanding will be guided by your description. Therefore, it is in your best interest to provide a sufficient amount of detail about your maze-solving solution in your comments order to reduce the chance for misinterpretation. |