Computer Science 315
Artificial Intelligence
Assignment 2 - AIMIA Chapter 3: Search
Now I ain't no monkey
I sure can't climb no tree
–
Oscar Woods,
"Lone Wolf Blues" (1936)
Due Wednesday, 03 October
In this problem set, you will write Python implementations of depth-first,
breadth-first, and uniform-cost search. If written efficiently, your code
will take up less than 80 (non-blank) lines of Python, much of it repeated
among files. You will test your
code first a simple problem: searching for goal nodes in a binary tree You will write and turn
in the following files, whose classes and methods you can see by clicking on
the file name below:
You may find it useful to implement a Node class within
search.py, as illustrated in Figure 3.9. To see what methods are
available to your code, here is the API for the
Problem class. You will call these methods, rather than implementing them
– unless you do the extra-credit work
of creating your own problem. In either case, should save
problem.py now.
I suggest sticking very close to the algorithm(s) in Figure 3.9; your Python
code should match the pseudocode nearly line-for-line. This approach takes a
little more discipline than just "winging it", but will get you to a
solution faster. The only extra thing you need to add is a call to the
takeAction method of the Problem class, which
should come right after you call your REMOVE-FRONT implementation to get
the first node from the fringe. This call will do something useful in the
problem you're solving – printing out state information, moving the
Quagent bot, etc.
Test #1: Using TREE-SEARCH to search a tree
When you're solving a problem by using a data
structure, the simplest test is often a problem that takes
the same form as your data structure. This
program will test your tree-search code by seeking goal nodes in a tree
–
in this case, a fully-balanced binary tree.
1   Each node in the
tree is assigned to be a goal or not with a specified probability, and
is a assigned a random step cost between 1 and 100. To run the test, type
python treetest.py depth goalprob
where depth is the depth of the desired tree, and
goalprob is the probability that a given node is a goal state.
Once your Search implementations are working, you will see how each
algorithm (DFS, BFS, UCS) visits each node, which will help you debug.
If you add more print statements to debug along the way, be sure to remove them
before submitting your solution: you will lose points for extra junk in
the output. Also, do not submit a modified treetest.py, because I will
test your solution with the original..
I tested the program with a depth of 3 and a goal probability of 0.2 (meaning
that around 20% of the nodes were goal states). If you want to use the same
random values each time, you can specify a seed value for the random-number
generator; e.g.:
python treetest.py 3 0.2 0
This program will print out the binary tree, showing the state on each tree node
(with goal nodes starred),
as well as its step cost and path cost. The program will then call your
DFS, BFS, and UCS algorithms in succession. If you've written these properly,
and called the takeAction method, you should see a list of the order
in which the states are visited for each algorithm. At the end of the list
should be the final state, or None if the tree contained no goal states.
If your search algorithm returns the final node on success, as it should,
you'll need to write a __repr__ (string representation) method for
your Node class, so that
it can be printed out
properly; otherwise, my code will just print out the machine address of the
Node object. I suggest returning the node's state as a string.
Test #2: Extra Credit
For extra credit, find a problem that can be solved by one or all of the
three search methods you've implemented, and implement the problem
in Python, based on the Problem API. As in the
TreeProblem example, you should put all the code
needed to run your test into a single file, and tell me how to run it. I suggest
the 8-Puzzle or 8-Queens Problem.
What to Turn In
Send me an email with the following files attached:
search.py,
dfsearch.py,
bfsearch.py,
ucsearch.py, and your extra-credit problem if you do it.
1You are welcome to look at this code, but don't
be confused into thinking that it will help you solve the problem.
The nodes you create in your solution will have different contents from the
binary-tree nodes used in this particular problem. It may be better to treat
each problem as a "black box" with which you communicate via the
Problem API.