Provided Code Skeleton
We have provided
( tar file or zip file)
all the code to get you started on your MP, which
means you will only have to write the search functions. Do not
modify provided code. You will only have to modify search.py.
maze.py
- getStart() :- Returns a tuple of the starting position, (row, col)
- getObjectives() :- Returns a list of tuples that correspond to the dot positions, [(row1, col1), (row2, col2)]
- isValidMove(row, col) :- Returns the boolean True if the (row, col) position is valid. Returns False otherwise.
- getNeighbors(row, col) :- Given a position, returns the list of tuples that correspond to valid neighbor positions. This will return at most 4 neighbors, but may return less.
search.py
There are 4 methods to implement in this file, namely bfs(maze),
dfs(maze), greedy(maze), and astar(maze).
(You may need to add another named search method if you
implement an additional search method for extra credit.)
Each of these
functions takes in a maze instance, and should return both the path
taken (as a list of tuples) and the number of states explored. The
maze instance provided will already be instantiated, and the above
methods will be accessible.
To understand how to run the MP, read the provided README.md or
run python3 mp1.py -h into your terminal. The following
command will display a maze
and let you create a path manually using the arrow keys.
python3 mp1.py --human maze.txt
The following command will run your astar search method on the maze.
python3 mp1.py --method astar maze.txt
You can also save your output picture as a file in tga format.
If your favorite document formatter doesn't handle tga, tools such as
gimp can convert it to other formats (e.g. jpg).
Tips
- In your implementation, make sure you get all the bookkeeping right. This includes handling
of repeated states (in particular, what happens when you find a better
path to a state already on the frontier) and saving the optimal solution
path. These topics have been extensively covered during the lectures.
- Pay attention to tiebreaking. If you have multiple nodes on the
frontier with the same minimum value of the evaluation function, the
speed of your search and the quality of the solution may depend on
which one you select for expansion.
- Implement all four strategies using a similar approach and coding style.
In particular, while DFS can be implemented very compactly using recursion,
you must store the frontier in an explicit stack for this assignment.
Among other things, limits on recursion depth can be (depending on your installation)
much lower than
the number of objects that you can pack into an explicit stack.
- You will be graded primarily on the correctness of your solution, not on the
efficiency and elegance of your data structures. For example, we don't
care whether your priority queue or repeated state detection uses
brute-force search, as long as you end up expanding (roughly) the
correct number of nodes and find the optimal solution. So, feel free
to use "dumb" data structures as long as it makes your life easier
and still enables you to find the solutions to all the inputs in a reasonable
amount of time.