![]() |
Assignment 3 Due 5:00 PM, Tuesday, Oct. 16th Department of Computer Science | ![]() |
sort function. It takes an optional keyword
argument named :key and a function applied to each
element before sorting. (setf queue (sort queue
#'< :key #'node-f))
Problem 1:
Write a function named effective-branching-factor that
has arguments for the solution path depth and the number of nodes
generated and returns the effective branching factor. Recall from
class that you must search for an approximation to the solution of the
polynomial. A binary search is very efficient for this. Return an
effective branching factor that results in a number of nodes that is
within 0.01 of the true number of nodes generated. For example:
CL-USER(62): (effective-branching-factor 6 2000) 3.345683 CL-USER(64): (effective-branching-factor 5 6) 1.0004883 CL-USER(65): (effective-branching-factor 50 60000) 1.2025168
Problem 2:
Solve a modified version of Graham's simple search problem by writing
a function named findpath that accepts a start and goal
state, a map, and t or nil to indicate the use of the hash table.
Your function must solve the search problem, print the effective
branching factor and the maximum queue length, then return the path
from the start state to the goal state.
The modification is to add costs to each link in the map. Represent
each successor by a list of the node letter and the cost of getting to
that node. If A is the first node that has two successors, B and C,
and it costs 2 to get to B and 5 to get to C, the map will be
represented as '((a (b 2) (c 5))). You may use an very
uninformative heuristic function for this that returns 0 for all states.
For example, the following calls show the benefit of using the hash table. First we solve the problem without the hash table, then again with the hash table.
CL-USER(7): (findpath 'a 'g '((a (b 1) (c 10) (d 1)) (b (b 1) (g 20)) (c (g 5)) (d (e 1)) (e (f 1)) (f (a 1))) nil) Effective branching factor is 9.411919. Max queue length is 45.0. (A C G) CL-USER(8): (findpath 'a 'g '((a (b 1) (c 10) (d 1)) (b (b 1) (g 20)) (c (g 5)) (d (e 1)) (e (f 1)) (f (a 1))) t) Effective branching factor is 2.3730469. Max queue length is 3.0. (A C G)
Draw this map on a piece of paper. Consider the start and goal nodes and the path that is returned. Type an explanation of why A* is so much more efficient for this problem when the hash table is used. Type your answer as a comment in the source code, clearly marked as Problem 2.
Problem 3:
Now you will apply A* to solve our robot example from previous
assignments. First, write a function named robot-path
that accepts the size of the square world, a list of barriers as lists
of x and y pairs not including the outer walls, the start state,
the goal state, a heuristic function to be used to calculate h for
any node, and t or nil to specify use of the hash table. Let the cost
of each action be equal to 1. Your
function must solve the search problem, print the
effective branching factor and the maximum queue length, the return
the solution path as lists of x, y pairs and the action as a
direction.
For example:
CL-USER(27): (robot-path 5 '((2 2)(2 3)(2 4)) '(1 1) '(5 5) #'(lambda (n) 0) t) Effective branching factor is 1.5427856. Max queue length is 9.0. (((1 1) START) ((2 1) E) ((3 2) NE) ((3 3) N) ((4 4) NE) ((5 5) NE))Now let's do this again with a better heuristic function. Let's use the smallest number of steps between a node and the goal. You must define the function
dist to do this, which simply returns the
maximum of the absolute value of the difference in x and the
difference in y.
CL-USER(28): (setf barriers (loop for y from 2 to 12 collect (list 10 y)))
((10 2) (10 3) (10 4) (10 5) (10 6) (10 7) (10 8) (10 9) (10 10) (10 11)
(10 12))
CL-USER(29): (robot-path 20 barriers '(1 1) '(20 20)
#'(lambda (n) (dist (node-state n) '(20 20))) t)
Effective branching factor is 1.1286695. Max queue length is 64.0.
(((1 1) START) ((2 2) NE) ((3 3) NE) ((4 4) NE) ((5 5) NE) ((6 6) NE)
((7 7) NE) ((8 8) NE) ((9 9) NE) ((9 10) N) ((9 11) N) ((9 12) N)
((10 13) NE) ((11 13) E) ((12 13) E) ((13 13) E) ((14 14) NE) ((15 15) NE)
((16 16) NE) ((17 17) NE) ((18 18) NE) ((19 19) NE) ((20 20) NE))
Problem 4:
To further explore the effects of different heuristic functions and of
the hash table, write a function named
robot-compare-hfuncs that has no arguments, performs a
total of six searches, and prints the following table. For this
function we don't care what it returns. The first two rows of results are for
solving a small problem with a world of size 5, barriers at (3 3) and
(3 4) a start state of (1 1) and a goal state of (4 4). The large
problem is for a size of 10, barriers at (5 y) as y goes from 2 to
7, a start state of (1 1) and a goal state of (10 10). The
"h = 0" heuristic function is a rather useless heuristic that is a constant zero for all nodes. The
"h = dist" heuristic function is the distance function.
CL-USER(35): (robot-compare-hfuncs)
Without Hash Table With Hash Table
Path Nodes MaxQ EBF Path Nodes MaxQ EBF
small h = 0 5 945 773 5.26 5 22 9 1.79
small h = dist 5 30 25 1.98 5 18 13 1.67
large h = dist 13 2809 2350 1.81 13 49 25 1.20
NIL
Type some comments comparing these numbers and explaining the
differences. Type at least 10 sentences.
Extra Credit Problem 1:
Let's say that it is harder for the robot to move diagonally than it
is for it to move N, S, E, or W. Modify this search problem to
reflect this and solve the problem again. Type some comments about the
resulting search paths and how they are different than the ones you
get from the original robot-path code.
Extra Credit Problem 2: Write a lisp function that prints the robot's world, including the outer walls, barriers, start and goal states and the solution path, using characters as shown below:
CL-USER(57): (setf barriers (append
(loop for y from 2 to 12 collect (list 10 y))
(loop for x from 10 downto 5 collect (list x 12))))
((10 2) (10 3) (10 4) (10 5) (10 6) (10 7) (10 8) (10 9) (10 10) (10 11)
(10 12) (10 12) (9 12) (8 12) (7 12) (6 12) (5 12))
CL-USER(58): (show-maze '(1 1) '(20 20) 20 barriers
(robot-path 20 barriers '(1 1) '(20 20)
#'(lambda (n) (dist '(20 20) (node-state n))) t))
######################
# G#
# . #
# . #
# . #
# . #
# . #
# . #
# ......... #
# .###### #
# . # #
# . # #
# . # #
# . # #
# . # #
# . # #
# . # #
# . # #
# . # #
# . # #
#S #
######################
NIL
Now I did it again with higher diagonal action costs being twice the cost of non-diagonal costs:
###################### # G# # . # # . # # . # # . # # . # # . # # . # # ###### . # # #. # # #. # # #. # # #. # # #. # # #. # # #. # # #. # # #. # # #. # #S......... # ######################