1111import sys
1212import bisect
1313
14+ infinity = float ('inf' )
15+
1416# ______________________________________________________________________________
1517
1618
@@ -98,7 +100,7 @@ def expand(self, problem):
98100 for action in problem .actions (self .state )]
99101
100102 def child_node (self , problem , action ):
101- "Fig. 3.10"
103+ "[ Fig. 3.10] "
102104 next = problem .result (self .state , action )
103105 return Node (next , self , action ,
104106 problem .path_cost (self .path_cost , self .state ,
@@ -462,7 +464,10 @@ def update_state(self, percept):
462464# ______________________________________________________________________________
463465
464466class OnlineSearchProblem (Problem ):
465- """ Fig. [4.23]
467+ """
468+ A problem which is solved by an agent executing
469+ actions, rather than by just computation.
470+ Carried in a deterministic and a fully observable environment.
466471 """
467472 def __init__ (self , initial , goal , graph ):
468473 self .initial = initial
@@ -477,13 +482,13 @@ def output(self, state, action):
477482
478483 def h (self , state ):
479484 """
480- returns least possible cost for the given state
485+ Returns least possible cost to reach a goal for the given state.
481486 """
482487 return self .graph .least_costs [state ]
483488
484489 def c (self , s , a , s1 ):
485490 """
486- returns a cost estimate to move from state 's' to state 's1'
491+ Returns a cost estimate for an agent to move from state 's' to state 's1'
487492 """
488493 return 1
489494
@@ -498,11 +503,11 @@ def goal_test(self, state):
498503
499504class LRTAStarAgent :
500505
501- """Fig. [ 4.24]
506+ """ [ Fig. 4.24]
502507 Abstract class for LRTA*-Agent. A problem needs to be
503508 provided which is an instanace of a subclass of Problem Class.
504509
505- Takes a OneDimStateSpaceProblem Fig. [ 4.23] as a problem
510+ Takes a OnlineSearchProblem [ Fig. 4.23] as a problem
506511 """
507512
508513 def __init__ (self , problem ):
@@ -537,7 +542,7 @@ def __call__(self, s1): # as of now s1 is a state rather than a percept
537542
538543 def LRTA_cost (self , s , a , s1 , H ):
539544 """
540- returns cost to move from state 's' to state 's1' plus
545+ Returns cost to move from state 's' to state 's1' plus
541546 estimated cost to get to goal from s1
542547 """
543548 print (s , a , s1 )
@@ -556,7 +561,8 @@ def LRTA_cost(self, s, a, s1, H):
556561
557562
558563def genetic_search (problem , fitness_fn , ngen = 1000 , pmut = 0.1 , n = 20 ):
559- """Call genetic_algorithm on the appropriate parts of a problem.
564+ """
565+ Call genetic_algorithm on the appropriate parts of a problem.
560566 This requires the problem to have states that can mate and mutate,
561567 plus a value method that scores states."""
562568 s = problem .initial_state
@@ -689,8 +695,10 @@ def distance_to_node(n):
689695 g .connect (node , neighbor , int (d ))
690696 return g
691697
692- # Simplified road map of Romania
693- Fig [3 , 2 ] = UndirectedGraph (dict (
698+ """ [Fig. 3.2]
699+ Simplified road map of Romania
700+ """
701+ romania_map = UndirectedGraph (dict (
694702 Arad = dict (Zerind = 75 , Sibiu = 140 , Timisoara = 118 ),
695703 Bucharest = dict (Urziceni = 85 , Pitesti = 101 , Giurgiu = 90 , Fagaras = 211 ),
696704 Craiova = dict (Drobeta = 120 , Rimnicu = 146 , Pitesti = 138 ),
@@ -704,7 +712,7 @@ def distance_to_node(n):
704712 Pitesti = dict (Rimnicu = 97 ),
705713 Rimnicu = dict (Sibiu = 80 ),
706714 Urziceni = dict (Vaslui = 142 )))
707- Fig [ 3 , 2 ] .locations = dict (
715+ romania_map .locations = dict (
708716 Arad = (91 , 492 ), Bucharest = (400 , 327 ), Craiova = (253 , 288 ),
709717 Drobeta = (165 , 299 ), Eforie = (562 , 293 ), Fagaras = (305 , 449 ),
710718 Giurgiu = (375 , 270 ), Hirsova = (534 , 350 ), Iasi = (473 , 506 ),
@@ -713,19 +721,20 @@ def distance_to_node(n):
713721 Sibiu = (207 , 457 ), Timisoara = (94 , 410 ), Urziceni = (456 , 350 ),
714722 Vaslui = (509 , 444 ), Zerind = (108 , 531 ))
715723
716- """
724+ """ [Fig. 4.9]
717725Eight possible states of the vacumm world
718- Each state is represented as "State if the left room" "State of the right room" "Room in which the agent is present"
719- 1 Dirty Dirty Left - DDL
720- 2 Dirty Dirty Right - DDR
721- 3 Dirty Clean Left - DCL
722- 4 Dirty Clean Right - DCR
723- 5 Clean Dirty Left - CDL
724- 6 Clean Dirty Right - CDR
725- 7 Clean Clean Left - CCL
726- 8 Clean Clean Right - CCR
726+ Each state is represented as
727+ * "State of the left room" "State of the right room" "Room in which the agent is present"
728+ 1 - DDL Dirty Dirty Left
729+ 2 - DDR Dirty Dirty Right
730+ 3 - DCL Dirty Clean Left
731+ 4 - DCR Dirty Clean Right
732+ 5 - CDL Clean Dirty Left
733+ 6 - CDR Clean Dirty Right
734+ 7 - CCL Clean Clean Left
735+ 8 - CCR Clean Clean Right
727736"""
728- Fig [ 4 , 9 ] = Graph (dict (
737+ vacumm_world = Graph (dict (
729738 State_1 = dict (Suck = ['State_7' , 'State_5' ], Right = ['State_2' ]),
730739 State_2 = dict (Suck = ['State_8' , 'State_4' ], Left = ['State_2' ]),
731740 State_3 = dict (Suck = ['State_7' ], Right = ['State_4' ]),
@@ -736,15 +745,10 @@ def distance_to_node(n):
736745 State_8 = dict (Suck = ['State_8' , 'State_6' ], Left = ['State_7' ])
737746 ))
738747
739- """
740- Fig. [4.23]
748+ """ [Fig. 4.23]
741749One-dimensional state space Graph
742750
743751"""
744-
745- # TODO: It's better to use some meaningful names rather
746- # than Fig[4, 9] or Fig[6, 1] to represent graphs in figures
747-
748752one_dim_state_space = Graph (dict (
749753 State_1 = dict (Right = 'State_2' ),
750754 State_2 = dict (Right = 'State_3' , Left = 'State_1' ),
@@ -762,12 +766,12 @@ def distance_to_node(n):
762766 State_6 = 3 )
763767
764768# Principal states and territories of Australia
765- Fig [ 6 , 1 ] = UndirectedGraph (dict (
769+ australia_map = UndirectedGraph (dict (
766770 T = dict (),
767771 SA = dict (WA = 1 , NT = 1 , Q = 1 , NSW = 1 , V = 1 ),
768772 NT = dict (WA = 1 , Q = 1 ),
769773 NSW = dict (Q = 1 , V = 1 )))
770- Fig [ 6 , 1 ] .locations = dict (WA = (120 , 24 ), NT = (135 , 20 ), SA = (135 , 30 ),
774+ australia_map .locations = dict (WA = (120 , 24 ), NT = (135 , 20 ), SA = (135 , 30 ),
771775 Q = (145 , 20 ), NSW = (145 , 32 ), T = (145 , 42 ),
772776 V = (145 , 37 ))
773777
@@ -954,8 +958,8 @@ class Wordlist:
954958 to check if a word is in the list, or wordlist.lookup(prefix)
955959 to see if prefix starts any of the words in the list."""
956960
957- def __init__ (self , filename , min_len = 3 ):
958- lines = open ( filename ) .read ().upper ().split ()
961+ def __init__ (self , file , min_len = 3 ):
962+ lines = file .read ().upper ().split ()
959963 self .words = [word for word in lines if len (word ) >= min_len ]
960964 self .words .sort ()
961965 self .bounds = {}
@@ -995,7 +999,7 @@ class BoggleFinder:
995999
9961000 def __init__ (self , board = None ):
9971001 if BoggleFinder .wordlist is None :
998- BoggleFinder .wordlist = Wordlist ("../data/ EN-text/wordlist" )
1002+ BoggleFinder .wordlist = Wordlist (DataFile ( " EN-text/wordlist") )
9991003 self .found = {}
10001004 if board :
10011005 self .set_board (board )
@@ -1135,52 +1139,25 @@ def do(searcher, problem):
11351139
11361140
11371141def compare_graph_searchers ():
1138- """Prints a table of results like this:
1139- >>> compare_graph_searchers()
1140- Searcher Fig[3, 2](A, B) Fig[3, 2](O, N) Fig[6, 1]
1141- breadth_first_tree_search < 21/ 22/ 59/B> <1158/1159/3288/N> < 7/ 8/ 22/WA>
1142- breadth_first_search < 7/ 11/ 18/B> < 19/ 20/ 45/N> < 2/ 6/ 8/WA>
1143- depth_first_graph_search < 8/ 9/ 20/B> < 16/ 17/ 38/N> < 4/ 5/ 11/WA>
1144- iterative_deepening_search < 11/ 33/ 31/B> < 656/1815/1812/N> < 3/ 11/ 11/WA>
1145- depth_limited_search < 54/ 65/ 185/B> < 387/1012/1125/N> < 50/ 54/ 200/WA>
1146- recursive_best_first_search < 5/ 6/ 15/B> <5887/5888/16532/N> < 11/12/ 43/WA>""" # noqa
1147- compare_searchers (problems = [GraphProblem ('Arad' , 'Bucharest' , Fig [3 , 2 ]),
1148- GraphProblem ('Oradea' , 'Neamt' , Fig [3 , 2 ]),
1149- GraphProblem ('Q' , 'WA' , Fig [6 , 1 ])],
1150- header = ['Searcher' , 'Fig[3, 2](Arad, Bucharest)' ,
1151- 'Fig[3, 2](Oradea, Neamt)' , 'Fig[6, 1]' ])
1142+ """
1143+ Prints a table of results like this:
1144+ >>> compare_graph_searchers()
1145+ Searcher romania_map(A, B) romania_map(O, N) australia_map
1146+ breadth_first_tree_search < 21/ 22/ 59/B> <1158/1159/3288/N> < 7/ 8/ 22/WA>
1147+ breadth_first_search < 7/ 11/ 18/B> < 19/ 20/ 45/N> < 2/ 6/ 8/WA>
1148+ depth_first_graph_search < 8/ 9/ 20/B> < 16/ 17/ 38/N> < 4/ 5/ 11/WA>
1149+ iterative_deepening_search < 11/ 33/ 31/B> < 656/1815/1812/N> < 3/ 11/ 11/WA>
1150+ depth_limited_search < 54/ 65/ 185/B> < 387/1012/1125/N> < 50/ 54/ 200/WA>
1151+ recursive_best_first_search < 5/ 6/ 15/B> <5887/5888/16532/N> < 11/12/ 43/WA>
1152+ """ # noqa
1153+ compare_searchers (problems = [GraphProblem ('Arad' , 'Bucharest' , romania_map ),
1154+ GraphProblem ('Oradea' , 'Neamt' , romania_map ),
1155+ GraphProblem ('Q' , 'WA' , australia_map )],
1156+ header = ['Searcher' , 'romania_map(Arad, Bucharest)' ,
1157+ 'romania_map(Oradea, Neamt)' , 'australia_map' ])
11521158
11531159# ______________________________________________________________________________
11541160
1155- __doc__ += """
1156- >>> romania = GraphProblem('Arad', 'Bucharest', Fig[3, 2])
1157- >>> breadth_first_tree_search(romania).solution()
1158- ['Sibiu', 'Fagaras', 'Bucharest']
1159- >>> breadth_first_search(romania).solution()
1160- ['Sibiu', 'Fagaras', 'Bucharest']
1161- >>> uniform_cost_search(romania).solution()
1162- ['Sibiu', 'Rimnicu', 'Pitesi', 'Bucharest']
1163- >>> depth_first_graph_search(romania).solution()
1164- ['Timisoara', 'Lugoj', 'Mehadia', 'Drobeta', 'Craiova', 'Pitesi', 'Bucharest']
1165- >>> iterative_deepening_search(romania).solution()
1166- ['Sibiu', 'Fagaras', 'Bucharest']
1167- >>> len(depth_limited_search(romania).solution())
1168- 50
1169- >>> astar_search(romania).solution()
1170- ['Sibiu', 'Rimnicu', 'Pitesti', 'Bucharest']
1171- >>> recursive_best_first_search(romania).solution()
1172- ['Sibiu', 'Rimnicu', 'Pitesi', 'Bucharest']
1173-
1174- >>> board = list('SARTELNID')
1175- >>> print_boggle(board)
1176- S A R
1177- T E L
1178- N I D
1179- >>> f = BoggleFinder(board)
1180- >>> len(f)
1181- 206
1182- """
1183-
11841161__doc__ += """
11851162Random tests
11861163>>> ' '.join(f.words())
0 commit comments