55sys .path .append (os .path .join (os .path .dirname (__file__ ), '..' ))
66from search import *
77from search import breadth_first_tree_search as bfts , depth_first_tree_search as dfts , \
8- depth_first_graph_search as dfgs , breadth_first_search as bfs , uniform_cost_search as ucs , \
8+ depth_first_graph_search as dfgs , breadth_first_graph_search as bfs , uniform_cost_search as ucs , \
99 astar_search as asts
10- from utils import Stack , FIFOQueue , PriorityQueue
10+ from utils import PriorityQueue
1111from copy import deepcopy
1212
1313root = None
2626
2727
2828def create_map (root ):
29- '''
30- This function draws out the required map.
31- '''
29+ """This function draws out the required map."""
3230 global city_map , start , goal
3331 romania_locations = romania_map .locations
3432 width = 750
@@ -260,17 +258,13 @@ def create_map(root):
260258
261259
262260def make_line (map , x0 , y0 , x1 , y1 , distance ):
263- '''
264- This function draws out the lines joining various points.
265- '''
261+ """This function draws out the lines joining various points."""
266262 map .create_line (x0 , y0 , x1 , y1 )
267263 map .create_text ((x0 + x1 ) / 2 , (y0 + y1 ) / 2 , text = distance )
268264
269265
270266def make_rectangle (map , x0 , y0 , margin , city_name ):
271- '''
272- This function draws out rectangles for various points.
273- '''
267+ """This function draws out rectangles for various points."""
274268 global city_coord
275269 rect = map .create_rectangle (
276270 x0 - margin ,
@@ -313,51 +307,51 @@ def make_legend(map):
313307
314308
315309def tree_search (problem ):
316- '''
310+ """
317311 Search through the successors of a problem to find a goal.
318312 The argument frontier should be an empty queue.
319313 Don't worry about repeated paths to a state. [Figure 3.7]
320314 This function has been changed to make it suitable for the Tkinter GUI.
321- '''
315+ """
322316 global counter , frontier , node
323- # print(counter)
317+
324318 if counter == - 1 :
325319 frontier .append (Node (problem .initial ))
326- # print(frontier)
320+
327321 display_frontier (frontier )
328322 if counter % 3 == 0 and counter >= 0 :
329323 node = frontier .pop ()
330- # print(node)
324+
331325 display_current (node )
332326 if counter % 3 == 1 and counter >= 0 :
333327 if problem .goal_test (node .state ):
334- # print(node)
328+
335329 return node
336330 frontier .extend (node .expand (problem ))
337- # print(frontier)
331+
338332 display_frontier (frontier )
339333 if counter % 3 == 2 and counter >= 0 :
340- # print(node)
334+
341335 display_explored (node )
342336 return None
343337
344338
345339def graph_search (problem ):
346- '''
340+ """
347341 Search through the successors of a problem to find a goal.
348342 The argument frontier should be an empty queue.
349343 If two paths reach a state, only use the first one. [Figure 3.7]
350344 This function has been changed to make it suitable for the Tkinter GUI.
351- '''
345+ """
352346 global counter , frontier , node , explored
353347 if counter == - 1 :
354348 frontier .append (Node (problem .initial ))
355349 explored = set ()
356- # print("Frontier: "+str(frontier))
350+
357351 display_frontier (frontier )
358352 if counter % 3 == 0 and counter >= 0 :
359353 node = frontier .pop ()
360- # print("Current node: "+str(node))
354+
361355 display_current (node )
362356 if counter % 3 == 1 and counter >= 0 :
363357 if problem .goal_test (node .state ):
@@ -366,18 +360,15 @@ def graph_search(problem):
366360 frontier .extend (child for child in node .expand (problem )
367361 if child .state not in explored and
368362 child not in frontier )
369- # print("Frontier: " + str(frontier))
363+
370364 display_frontier (frontier )
371365 if counter % 3 == 2 and counter >= 0 :
372- # print("Explored node: "+str(node))
373366 display_explored (node )
374367 return None
375368
376369
377370def display_frontier (queue ):
378- '''
379- This function marks the frontier nodes (orange) on the map.
380- '''
371+ """This function marks the frontier nodes (orange) on the map."""
381372 global city_map , city_coord
382373 qu = deepcopy (queue )
383374 while qu :
@@ -388,63 +379,92 @@ def display_frontier(queue):
388379
389380
390381def display_current (node ):
391- '''
392- This function marks the currently exploring node (red) on the map.
393- '''
382+ """This function marks the currently exploring node (red) on the map."""
394383 global city_map , city_coord
395384 city = node .state
396385 city_map .itemconfig (city_coord [city ], fill = "red" )
397386
398387
399388def display_explored (node ):
400- '''
401- This function marks the already explored node (gray) on the map.
402- '''
389+ """This function marks the already explored node (gray) on the map."""
403390 global city_map , city_coord
404391 city = node .state
405392 city_map .itemconfig (city_coord [city ], fill = "gray" )
406393
407394
408395def display_final (cities ):
409- '''
410- This function marks the final solution nodes (green) on the map.
411- '''
396+ """This function marks the final solution nodes (green) on the map."""
412397 global city_map , city_coord
413398 for city in cities :
414399 city_map .itemconfig (city_coord [city ], fill = "green" )
415400
416401
417402def breadth_first_tree_search (problem ):
418403 """Search the shallowest nodes in the search tree first."""
419- global frontier , counter
404+ global frontier , counter , node
420405 if counter == - 1 :
421- frontier = FIFOQueue ()
422- return tree_search (problem )
406+ frontier = deque ()
407+
408+ if counter == - 1 :
409+ frontier .append (Node (problem .initial ))
410+
411+ display_frontier (frontier )
412+ if counter % 3 == 0 and counter >= 0 :
413+ node = frontier .popleft ()
414+
415+ display_current (node )
416+ if counter % 3 == 1 and counter >= 0 :
417+ if problem .goal_test (node .state ):
418+ return node
419+ frontier .extend (node .expand (problem ))
420+
421+ display_frontier (frontier )
422+ if counter % 3 == 2 and counter >= 0 :
423+ display_explored (node )
424+ return None
423425
424426
425427def depth_first_tree_search (problem ):
426428 """Search the deepest nodes in the search tree first."""
427429 # This search algorithm might not work in case of repeated paths.
428- global frontier , counter
430+ global frontier , counter , node
429431 if counter == - 1 :
430- frontier = Stack ()
431- return tree_search (problem )
432+ frontier = [] # stack
433+
434+ if counter == - 1 :
435+ frontier .append (Node (problem .initial ))
436+
437+ display_frontier (frontier )
438+ if counter % 3 == 0 and counter >= 0 :
439+ node = frontier .pop ()
440+
441+ display_current (node )
442+ if counter % 3 == 1 and counter >= 0 :
443+ if problem .goal_test (node .state ):
444+ return node
445+ frontier .extend (node .expand (problem ))
446+
447+ display_frontier (frontier )
448+ if counter % 3 == 2 and counter >= 0 :
449+ display_explored (node )
450+ return None
432451
433452
434- def breadth_first_search (problem ):
453+ def breadth_first_graph_search (problem ):
435454 """[Figure 3.11]"""
436455 global frontier , node , explored , counter
437456 if counter == - 1 :
438457 node = Node (problem .initial )
439458 display_current (node )
440459 if problem .goal_test (node .state ):
441460 return node
442- frontier = FIFOQueue ()
443- frontier .append (node )
461+
462+ frontier = deque ([node ]) # FIFO queue
463+
444464 display_frontier (frontier )
445465 explored = set ()
446466 if counter % 3 == 0 and counter >= 0 :
447- node = frontier .pop ()
467+ node = frontier .popleft ()
448468 display_current (node )
449469 explored .add (node .state )
450470 if counter % 3 == 1 and counter >= 0 :
@@ -461,10 +481,30 @@ def breadth_first_search(problem):
461481
462482def depth_first_graph_search (problem ):
463483 """Search the deepest nodes in the search tree first."""
464- global frontier , counter
484+ global counter , frontier , node , explored
465485 if counter == - 1 :
466- frontier = Stack ()
467- return graph_search (problem )
486+ frontier = [] # stack
487+ if counter == - 1 :
488+ frontier .append (Node (problem .initial ))
489+ explored = set ()
490+
491+ display_frontier (frontier )
492+ if counter % 3 == 0 and counter >= 0 :
493+ node = frontier .pop ()
494+
495+ display_current (node )
496+ if counter % 3 == 1 and counter >= 0 :
497+ if problem .goal_test (node .state ):
498+ return node
499+ explored .add (node .state )
500+ frontier .extend (child for child in node .expand (problem )
501+ if child .state not in explored and
502+ child not in frontier )
503+
504+ display_frontier (frontier )
505+ if counter % 3 == 2 and counter >= 0 :
506+ display_explored (node )
507+ return None
468508
469509
470510def best_first_graph_search (problem , f ):
@@ -483,7 +523,7 @@ def best_first_graph_search(problem, f):
483523 display_current (node )
484524 if problem .goal_test (node .state ):
485525 return node
486- frontier = PriorityQueue (min , f )
526+ frontier = PriorityQueue (' min' , f )
487527 frontier .append (node )
488528 display_frontier (frontier )
489529 explored = set ()
@@ -525,9 +565,9 @@ def astar_search(problem, h=None):
525565# Remove redundant code.
526566# Make the interchangbility work between various algorithms at each step.
527567def on_click ():
528- '''
568+ """
529569 This function defines the action of the 'Next' button.
530- '''
570+ """
531571 global algo , counter , next_button , romania_problem , start , goal
532572 romania_problem = GraphProblem (start .get (), goal .get (), romania_map )
533573 if "Breadth-First Tree Search" == algo .get ():
@@ -546,8 +586,8 @@ def on_click():
546586 display_final (final_path )
547587 next_button .config (state = "disabled" )
548588 counter += 1
549- elif "Breadth-First Search" == algo .get ():
550- node = breadth_first_search (romania_problem )
589+ elif "Breadth-First Graph Search" == algo .get ():
590+ node = breadth_first_graph_search (romania_problem )
551591 if node is not None :
552592 final_path = bfs (romania_problem ).solution ()
553593 final_path .append (start .get ())
@@ -605,7 +645,7 @@ def main():
605645 algorithm_menu = OptionMenu (
606646 root ,
607647 algo , "Breadth-First Tree Search" , "Depth-First Tree Search" ,
608- "Breadth-First Search" , "Depth-First Graph Search" ,
648+ "Breadth-First Graph Search" , "Depth-First Graph Search" ,
609649 "Uniform Cost Search" , "A* - Search" )
610650 Label (root , text = "\n Search Algorithm" ).pack ()
611651 algorithm_menu .pack ()
0 commit comments