In this assignment you will extend the problem solving framework
by adding an automatic problem solving capability.
This will be accomplished in the following steps:
- Implement and test State Space Search on simple
problems (see lecture notes in menu)
- Add GUI controls to initiate automatic solving and report
results
- Add heuristics to the 8-Puzzle problem
- Implement and test A* Search on the 8-Puzzle
- (Extra credit) Implement and test Enhanced A* Search on
the 8-Puzzle
The top-level framework classes involved in automatic solving are shown
in the diagram below.
- Problem: Already exists in the framework.problem
package
- Solution: Created by you in the framework.solution
package for the recent graph lab exercise
- Solver: A new abstract class for framework.solution
that implements generic aspects of state space search and needs to
be subclassed
- Statistics: A new concrete class
for framework.solution used by Solver to manage
solution statistics
Note that the
java.util.Queue interface type is also involved,
allowing reuse of
Solver code for both basic state space search
and A* search.
Listings of the new files
Solver.java and
Statistics.java are shown in the
menu to the left. They should be downloaded and placed into
your
framework.solution package.
State space search is implemented by extending the
Solver class
as shown below.
A skeletal form for
StateSpaceSolver.java is shown
in the menu to the left. It should be placed in
the
framework.solution package. Also shown is a
StateSpaceSolverTest.java
test class.
Develop
StateSpaceSolver using the steps below. See the Javadoc
comments for more details.
- Write the occursOnPath method and test it
with testOccursOnPath
- Write the expand method and test it
with testExpand. Note:
- The call to doMove in expand expects
a State, while expand's argument u is
a Vertex.
The Vertex class wraps a data field of
type Object, so that any object can participate in
graphs and state spaces.
You can get the state from the vertex
using (State)u.getData()
- Complete the StateSpaceSolver constructor. This requires
calling the superclass's setQueue method with a double-ended
queue. The java.util.LinkedList class is appropriate for
this. See how a double-ended queue is used in
the GraphSearcher class (Graph Lab Exercise from menu at left).
- Override the add method. This requires checking the
search type and adding at the appropriate location.
- Test the solver with testSolve
When all tests succeed proceed to the next step.
7-move Farmer, Wolf, Goat, and Cabbage problem:
Breadth-First State Space Search
------------------------------
Solution length 7
Solution time 2
Num of queue ops 31
Max queue size 4
7-move Farmer, Wolf, Goat, and Cabbage problem:
Depth-First State Space Search
------------------------------
Solution length 7
Solution time 0
Num of queue ops 21
Max queue size 3
6-move Arithmetic problem:
Breadth-First State Space Search
------------------------------
Solution length 6
Solution time 5
Num of queue ops 2090
Max queue size 1065
6-move Arithmetic problem:
Depth-First State Space Search
------------------------------
Solution length 4846
Solution time 417
Num of queue ops 19515
Max queue size 9804
5-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 5
Solution time 14
Num of queue ops 139
Max queue size 38
5-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 4485
Solution time 450
Num of queue ops 13127
Max queue size 4022
10-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 10
Solution time 2
Num of queue ops 2611
Max queue size 662
10-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 3208
Solution time 218
Num of queue ops 9394
Max queue size 2903
13-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 13
Solution time 6
Num of queue ops 8273
Max queue size 2328
13-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 3135
Solution time 208
Num of queue ops 9174
Max queue size 2833
18-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 18
Solution time 119
Num of queue ops 157751
Max queue size 44004
18-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 2056
Solution time 89
Num of queue ops 6034
Max queue size 1867
20-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 20
Solution time 473
Num of queue ops 420247
Max queue size 111460
20-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 3380
Solution time 246
Num of queue ops 9891
Max queue size 3054
24-move 8-Puzzle problem:
Breadth-First State Space Search
------------------------------
Solution length 24
Solution time 4725
Num of queue ops 3926555
Max queue size 1109388
24-move 8-Puzzle problem:
Depth-First State Space Search
------------------------------
Solution length 2374
Solution time 120
Num of queue ops 6950
Max queue size 2147
From testExpand:
framework.solution.Solution@5679c6c6
In this step you will modify your problem solver GUI to allow users to
solve the current problem using either breadth-first or depth-first
state space search.
The requirements for GUI behavior are given below. You can refer to
"before" and "after" snapshots accessible from the menu to the left.
You need not copy the examples exactly; you can use any controls that
meet the requirements, and you are encouraged to
make your presentations more interesting.
- The user can select either breadth-first or depth-first
search
- Clicking Solve causes the following:
- The selected type of search begins from the current
state
- The search statistics are displayed
- The move buttons become disabled
- The Solve button becomes disabled
- The Next button becomes enabled
- Clicking Next causes the next state in the solution to be
displayed
- Clicking Reset causes the following:
- The initial state of the problem is displayed
- The move buttons become enabled
- The Solve button becomes enabled
- The Next button becomes disabled
Here are suggestions for your
ProblemGUI class:
- In the constructor create two StateSpaceSolver objects:
one for BFS and one for DFS
- Maintain an instance field of type Solver and have the
listener for your search selection control (e.g. ChoiceBox)
appropriately set the field to one of these objects
- The Solver method that initiates the search
is solve. For an example, see the solveProblem method
at the bottom of the test class StateSpaceSolverTest.java
(see left).
- The Solver class maintains search statistics that you can
obtain using its getStatistics method (also exemplified
in StateSpaceSolverTest.java)
- The Solver class produces a Solution object from
which you can extract solution states for display in
your Next button event handler. You developed
the Solution class in the graphs lab exercise. See
the SolutionTest.java file (at left) for an example of how
it is used.
- Bindings are useful for managing the disabling of buttons. For
example, to make the Next button enabled whenever
the Solve button is disabled, use:
In this step you will add heuristics to the 8-Puzzle and implement A*
search. Refer to the informed search lecture notes (see menu).
To begin, add the following to your
State.java interface in
the
framework.problem package:
This default method will allow A* search to work on problems too simple
to warrant heuristics, while it can be overridden for problems like the
8-Puzzle.
Your
PuzzleState class must override the
getHeuristic
method.
To facilitate testing, you should organize your added code as shown
below. Note that you can test either the "number of tiles out of place"
heuristic or the "sum of Manhattan distances" heuristic by
appropriately commenting and uncommenting lines.
Then you can test your heuristics using this
PuzzleHeuristicTest.java
file, also listed in the menu. (Simply create a new class with this name in
the
domains.puzzle package under
Test Packages,
replace its contents with that given here, and run the file.)
Implementing A* search in the problem solver requires:
- Extending
the StateSpaceSolver class, as shown below
- Modifying the ProblemGUI class to allow:
- Selection of A* as a search option
- Selection from among problem benchmarks
A skeletal form for
AStarSolver.java is shown below.
It should be placed in the
framework.solution package.
Note that the
java.util.PriorityQueue works for the required
queue.
In order to test heuristics and A* search, we need to add an A* search
option to the GUI, and we need to allow the user to choose among
problem benchmarks.
The screenshot below illustrates this.
- Create an AStarSolver object to be used in the same way
the two StateSpaceSolver objects were used for BFS and DFS,
and add A* search to the existing options
- To manage benchmarks:
- Create a simple Benchmark class in
the framework.problem package that stores and provides
getters for a benchmark's name (for example, "Bench 5: 20 moves"),
start state, and goal state. Override the toString
method to return the name.
- Add an instance field and getter to the framework's Problem
class that stores a list of benchmarks
- In the PuzzleProblem constructor, create and store
the eight 8-Puzzle benchmarks. These are shown in the Informed
Search presentation (see menu at left) under "A* Performance".
(Note: none of the other
problems require benchmarks; they will simply have empty
benchmark options.)
- To use benchmarks in ProblemGUI:
- Create a selection control (e.g. ChoiceBox) and give
it benchmark options like this:
Each benchmark's toString method will be used to label
the selection options.
-
Suppose the selection control's name is "benchmarkOptions."
In its value listener, obtain the selected
benchmark like this:
The resulting Benchmark object has the information
needed to update the Problem object's initial and
current state before updating the display.
- The benchmark control should be disabled when the user is
stepping through a generated solution. The bind method
is useful for this.
When your
ProblemApplication.java file runs correctly:
- Make sure your identifying information is in the class comments
of all your files
- Zip (compress) your src folder as
src.zip.
- Submit src.zip by going to
and clicking Submission under Assignment:
Automated Problem Solving.
Note the general
Submission Policy in the menu at left.
Your project will be inspected, tested, and run by the lab instructor. Grading criteria:
- (10 points) Successful implementation and testing
of StateSpaceSolver.
- (10 points) Successful modification of ProblemGUI
for automated problem solving.
- (10 points) Successful implementation of 8-Puzzle
heuristics and A* search.
- (8 points) Extra credit: Successful implementation of
enhanced A* search and demonstration on the 8-Puzzle.