CS662 Assignment 2: Search
Assigned: September 4
Due: September 13.
30 points
To turn in: typed or handwritten answers to question 1 and the
questions at the end of the assignment. Also, please check your code
into your Subversion repository under a directory named assignment2.
Question 1: (10 points) Environments. For each of the following problems,
characterize its environment according to the six dimensions described
by Russell and Norvig (fully/partially observable, static/dynamic,
deterministic/stochastic, discrete/continuous, episodic/sequential,
single/multi-agent). If you feel that it's not clear from the given
description, please give any details or assumptions you feel are
needed.
- An agent that is able to play poker. Assume that the agent has a
digital representation of its and the other players' hands, but not
a camera or any other way to observe the players directly.
- An agent that is able to identify photos of USF faculty. The
agent receives a set of digital photos and, for each photo, prints
out the name of the faculty member in the photo. No learning is
involved.
- An agent that is able to play tennis. Assume that we build a
robot with a tennis racket attached to it. It needs to move around
the court, serve and return, and otherwise play tennis against a
person.
- An agent that can solve crossword puzzles. Assume that the
agent has a digital representation of the puzzle and an online
dictionary that it can use.
- An automotive assembly agent. Assume that the agent is sationed
on a conveyer belt and has a robot arm and a camera. As cars come
down the assembly line, the agent must determine the particular
model and attach the correct door onto the car.
Question 2 (20 points total) Search.
In this problem, you'll be helping the members of the rock band U2
get to a concert on time.
Consider the following problem:
U2 has a concert that starts in 17 minutes and they must all cross a
bridge to get there. All four men begin on the same side of the
bridge. You must help them across to the other side. It is
night. There is one flashlight. A maximum of two people can cross at
one time. Any party who crosses, either 1 or 2 people, must have the
flashlight with them. The flashlight must be walked back and forth, it
cannot be thrown, etc. Each band member walks at a different speed. A
pair must walk together at the rate of the slower man's pace:
Bono: 1 minute to cross
Edge: 2 minutes to cross
Adam: 5 minutes to cross
Larry: 10 minutes to cross
For example: if Bono and Larry walk across first, 10 minutes have
elapsed when they get to the other side of the bridge. If Larry then
returns with the flashlight, a total of 20 minutes have passed and you
have failed the mission.
(note: this is a fairly well-known puzzle, and solutions to it
undoubtedly can be found on the Web. I would suggest that you try to
solve it yourself first. This will give you a much better
understanding of the problem.)
A skeleton of the code needed to solve the problem can be found here. This will help provide some
structure and guidance for solving the problem.
- (10 points) To begin, complete the U2State class. To represent
a problem state, we'll use a list containing the band members on the
left bank, a list containing the band members on the right bank, a
variable indicating whether the flashlight is on the left or the
right, integers for time elapsed, depth and fvalue, and a pointer
back to the previous or parent state (this will be useful for
printing the
solution)
I've provided __init__, __lt__, and __hash__. You should implement
__repr__, __eq__, __le__, __gt__, __ge__, isGoal, isFailure, and
successors. Most of these are only a couple of lines.
The exception to this is successors, which is the most complex
method in this assignment. For a given state, successors should
consider all possible legal actions and, for each action,
create the state that would result of that action was applied. It
should return a list of these states.
For example, one state might be: (['Edge',
'Bono'],['Larry','Adam'],flashlight='Left',time elapsed=10). The
possible moves here are: Edge crosses alone, Bono crosses alone, or
they go together. So the successor method for this state would
return:
[ (['Edge'], ['Bono','Larry','Adam'], Right, 11), (['Bono'],
['Edge','Larry','Adam'], Right, 12) , ([], ['Edge', 'Bono','Larry','Adam'], Right, 12)]
Note: you may be tempted to try to put some "smarts" in successors
to only pick "good" moves. Resist this temptation - we'll use the
search algorithms to select among states.
- Search. Once we have our state representation built, we can think
about how to search - recall that search is just a mechanism for
considering different states in a particular order.
(5 points). To begin, we'll need a function called search. It should
take as input an initial state and a search queue. (I've provided
the prototype for you.)
Search should repeatedly:
- dequeue the front state in the search queue
- check to see if it is a goal. If so, we are done. Print out
the solution.
- If not, place the state in the closed list, and generate its
successors.
- For each successor, check to see if it is in your closed list
(i.e. they've already been visited). If so, discard it. Also check
to see if it returns true for isFailure, and if so, discard
it.
- Enqueue remaining state.
You should implement the closed list as a dictionary with states as
keys and 'True' as a value.
- Search queues. (5 points) By using different sorts of queues, we can
implement different algorithms. In this assignment, we'll implement
three search algorithms: BFS, DFS, and A*.
I've provided you with an abstract base class called
SearchQueue. You'll want to subclass this to implement BFSQueue,
DFSQueue, and AStarQueue. Recall that the queues should work as
follows:
- BFSQueue should work as a traditional queue: states are
enqueued at the rear and dequeued at the front.
- DFSQueue should work like a stack: states are pushed onto the
front and also popped from the front.
- AStarQueue should function as a priority queue. States
should be removed from the queue in order of ascending f-value,
where f = g + h. g is the depth in the queue and h is a
heuristic or estimate of the distance from the state to the
goal. For this problem, h = the time needed for the
slowest person remaining to cross the bridge.
On implementation: you should not completely sort the
AStarQueue every time a new state is added - this is
inefficient. Instead, you may choose one of the following solutions:
- Append new states to the rear of the queue and, when
dequeueing, find the minimal element in the list. (the min()
function will help here)
- Use the heapq module to maintain the list as a priority
queue.
Run each of the algorithms on the problem and prepare a table that
lists for each algorithm:
- Number of states generated
- Number of states dequeued
- Optimal solution found? (yes/no)
Turn this table in along with your source code. Also, please
provide both a "main" that allows your code to be run from the
command line and a README describing how to run it.