1 ; Winston & Horn (3rd Edition) Chapter 19
4 ; First set up the network
6 (setf (get 's
'neighbors
) '(a d
)
7 (get 'a
'neighbors
) '(s b d
)
8 (get 'b
'neighbors
) '(a c e
)
9 (get 'c
'neighbors
) '(b)
10 (get 'd
'neighbors
) '(s a e
)
11 (get 'e
'neighbors
) '(b d f
)
12 (get 'f
'neighbors
) '(e))
14 (setf (get 's
'coordinates
) '(0 3)
15 (get 'a
'coordinates
) '(4 6)
16 (get 'b
'coordinates
) '(7 6)
17 (get 'c
'coordinates
) '(11 6)
18 (get 'd
'coordinates
) '(3 0)
19 (get 'e
'coordinates
) '(6 0)
20 (get 'f
'coordinates
) '(11 3))
23 ; The extend function is used everywhere to provide a new queue
26 (print (reverse path
)) ; for observing what is happening
27 (mapcar #'(lambda (new-node) (cons new-node path
))
28 (remove-if #'(lambda (neighbor) (member neighbor path
))
29 (get (first path
) 'neighbors
))))
33 (defun depth-first (start finish
&optional
(queue (list (list start
))))
34 (cond ((endp queue
) nil
) ; Queue empty?
35 ((eq finish
(first (first queue
))) ; finish found?
36 (reverse (first queue
)))
40 (append (extend (first queue
))
43 ; breadth first search
45 (defun breadth-first (start finish
&optional
(queue (list (list start
))))
46 (cond ((endp queue
) nil
) ; Queue empty?
47 ((eq finish
(first (first queue
))) ; finish found?
48 (reverse (first queue
)))
53 (extend (first queue
)))))))
57 (defun best-first (start finish
&optional
(queue (list (list start
))))
58 (cond ((endp queue
) nil
) ; Queue empty?
59 ((eq finish
(first (first queue
))) ; finish found?
60 (reverse (first queue
)))
64 (sort (append (extend (first queue
))
66 #'(lambda (p1 p2
) (closerp p1 p2 finish
)))))))
70 (defun square (x) (* x x
))
72 (defun straight-line-distance (node-1 node-2
)
73 (let ((coord-1 (get node-1
'coordinates
))
74 (coord-2 (get node-2
'coordinates
)))
75 (sqrt (float (+ (square (- (first coord-1
) (first coord-2
)))
76 (square (- (second coord-1
) (second coord-2
))))))))
78 (defun closerp (path-1 path-2 target-node
)
79 (< (straight-line-distance (first path-1
) target-node
)
80 (straight-line-distance (first path-2
) target-node
)))
86 (defun hill-climb (start finish
&optional
(queue (list (list start
))))
87 (cond ((endp queue
) nil
) ; Queue empty?
88 ((eq finish
(first (first queue
))) ; finish found?
89 (reverse (first queue
)))
93 (append (sort (extend (first queue
))
95 (closerp p1 p2 finish
)))
100 ; branch and bound search (shortest length guarenteed)
102 (defun branch-and-bound (start finish
&optional
(queue (list (list start
))))
103 (cond ((endp queue
) nil
) ; Queue empty?
104 ((eq finish
(first (first queue
))) ; finish found?
105 (reverse (first queue
)))
109 (sort (append (extend (first queue
))
113 (defun shorterp (path-1 path-2
)
114 (< (path-length path-1
) (path-length path-2
)))
116 (defun path-length (path)
117 (if (endp (rest path
))
119 (+ (straight-line-distance (first path
) (second path
))
120 (path-length (rest path
)))))
124 ; pert chart searching (problem 19-7)
126 (setf (get 's
'successors
) '(a d
)
127 (get 'a
'successors
) '(b d
)
128 (get 'b
'successors
) '(c e
)
129 (get 'c
'successors
) '()
130 (get 'd
'successors
) '(e)
131 (get 'e
'successors
) '(f)
132 (get 'f
'successors
) '())
134 (setf (get 's
'time-consumed
) 3
135 (get 'a
'time-consumed
) 2
136 (get 'b
'time-consumed
) 4
137 (get 'c
'time-consumed
) 3
138 (get 'd
'time-consumed
) 3
139 (get 'e
'time-consumed
) 2
140 (get 'f
'time-consumed
) 1)
142 (defun pextend (path)
143 (mapcar #'(lambda (new-node) (cons new-node path
))
144 (remove-if #'(lambda (successor) (member successor path
))
145 (get (first path
) 'successors
))))
147 (defun all-paths (start &optional
(queue (list (list start
))))
148 (let ((extended (pextend (first queue
))))
149 (cond ((endp extended
)
150 (mapcar #'reverse queue
))
153 (sort (append extended
(rest queue
))
154 #'first-path-incomplete-p
))))))
156 (defun first-path-incomplete-p (p1 p2
)
157 (not (endp (pextend p1
))))
160 ; Pert chart searching (problem 19-8)
162 (defun time-consumed (path)
165 (+ (get (first path
) 'time-consumed
)
166 (time-consumed (rest path
)))))
168 (defun longerp (p1 p2
) (> (time-consumed p1
) (time-consumed p2
)))
170 (defun critical-path (start &optional
(queue (list (list start
))))
171 (let ((extended (pextend (first queue
))))
172 (cond ((endp extended
)
173 (reverse (first (sort queue
#'longerp
))))
176 (sort (append extended
(rest queue
))
177 #'first-path-incomplete-p
))))))