@@ -212,27 +212,36 @@ def f(n):
212
212
#______________________________________________________________________________
213
213
## Other search algorithms
214
214
215
- def recursive_best_first_search (problem ):
215
+ def recursive_best_first_search (problem , h = None ):
216
216
"[Fig. 4.5]"
217
+ h = h or problem .h
218
+
217
219
def RBFS (problem , node , flimit ):
218
220
if problem .goal_test (node .state ):
219
- return node
220
- successors = expand (node , problem )
221
+ return node , 0 # (The second value is immaterial)
222
+ successors = node . expand (problem )
221
223
if len (successors ) == 0 :
222
224
return None , infinity
223
225
for s in successors :
224
- s .f = max (s .path_cost + s . h , node .f )
226
+ s .f = max (s .path_cost + h ( s ) , node .f )
225
227
while True :
226
- successors .sort (lambda x ,y : x .f - y .f ) # Order by lowest f value
228
+ successors .sort (lambda x ,y : cmp ( x .f , y .f ) ) # Order by lowest f value
227
229
best = successors [0 ]
228
230
if best .f > flimit :
229
231
return None , best .f
230
- alternative = successors [1 ]
231
- result , best .f = RBFS (problem , best , min (flimit , alternative ))
232
+ if len (successors ) == 1 :
233
+ new_flimit = flimit
234
+ else :
235
+ alternative = successors [1 ]
236
+ new_flimit = min (flimit , alternative .f )
237
+ result , best .f = RBFS (problem , best , new_flimit )
232
238
if result is not None :
233
- return result
234
- return RBFS (Node (problem .initial ), infinity )
239
+ return result , best .f
235
240
241
+ node = Node (problem .initial )
242
+ node .f = h (node )
243
+ result , bestf = RBFS (problem , node , infinity )
244
+ return result
236
245
237
246
def hill_climbing (problem ):
238
247
"""From the initial node, keep choosing the neighbor with highest value,
@@ -721,7 +730,7 @@ def __repr__(self):
721
730
def compare_searchers (problems , header , searchers = [breadth_first_tree_search ,
722
731
breadth_first_graph_search , depth_first_graph_search ,
723
732
iterative_deepening_search , depth_limited_search ,
724
- astar_search ]):
733
+ astar_search , recursive_best_first_search ]):
725
734
def do (searcher , problem ):
726
735
p = InstrumentedProblem (problem )
727
736
searcher (p )
@@ -732,13 +741,14 @@ def do(searcher, problem):
732
741
def compare_graph_searchers ():
733
742
"""Prints a table of results like this:
734
743
>>> compare_graph_searchers()
735
- Searcher Romania(A,B) Romania(O, N) Australia
736
- breadth_first_tree_search < 21/ 22/ 59/B> <1158/1159/3288/N> < 7/ 8/ 22/WA>
737
- breadth_first_graph_search < 10/ 19/ 26/B> < 19/ 45/ 45/N> < 5/ 8/ 16/WA>
738
- depth_first_graph_search < 9/ 15/ 23/B> < 16/ 27/ 39/N> < 4/ 7/ 13/WA>
739
- iterative_deepening_search < 11/ 33/ 31/B> < 656/1815/1812/N> < 3/ 11/ 11/WA>
740
- depth_limited_search < 54/ 65/ 185/B> < 387/1012/1125/N> < 50/ 54/ 200/WA>
741
- astar_search < 3/ 4/ 9/B> < 8/ 10/ 22/N> < 2/ 3/ 6/WA> """
744
+ Searcher Romania(A,B) Romania(O, N) Australia
745
+ breadth_first_tree_search < 21/ 22/ 59/B> <1158/1159/3288/N> < 7/ 8/ 22/WA>
746
+ breadth_first_graph_search < 10/ 19/ 26/B> < 19/ 45/ 45/N> < 5/ 8/ 16/WA>
747
+ depth_first_graph_search < 9/ 15/ 23/B> < 16/ 27/ 39/N> < 4/ 7/ 13/WA>
748
+ iterative_deepening_search < 11/ 33/ 31/B> < 656/1815/1812/N> < 3/ 11/ 11/WA>
749
+ depth_limited_search < 54/ 65/ 185/B> < 387/1012/1125/N> < 50/ 54/ 200/WA>
750
+ astar_search < 3/ 4/ 9/B> < 8/ 10/ 22/N> < 2/ 3/ 6/WA>
751
+ recursive_best_first_search < 200/ 201/ 601/B> < 71/ 72/ 213/N> < 11/ 12/ 43/WA> """
742
752
compare_searchers (problems = [GraphProblem ('A' , 'B' , romania ),
743
753
GraphProblem ('O' , 'N' , romania ),
744
754
GraphProblem ('Q' , 'WA' , australia )],
@@ -760,6 +770,8 @@ def compare_graph_searchers():
760
770
'B'
761
771
>>> astar_search(ab).state
762
772
'B'
773
+ >>> recursive_best_first_search(ab).state
774
+ 'B'
763
775
>>> [node.state for node in astar_search(ab).path()]
764
776
['B', 'P', 'R', 'S', 'A']
765
777
0 commit comments