#!/usr/bin/python """ This is a basic example of a best-first search. It opens up a graph file (as described in the specs), and then searches from the start node to a goal node, printing out its progress as it goes. Your job is to implement the PriorityQueue class that it makes use of. """ __author__ = "Adam A. Smith" __version__ = "2023.09.13" from priorityqueue import PriorityQueue def _extract_paths_and_scores(lines: list) -> tuple: # set up paths = {} scores = {} # go line by line, parsing the tokens for line in lines: tokens = line.split("\t") if len(tokens) <= 1: continue elif len(tokens) == 2: neighbors = () else: neighbors = tuple(tokens[2].split(",")) scores[tokens[0]] = int(tokens[1]) paths[tokens[0]] = neighbors # tuple to ensure it's constant return (paths, scores) # do the best-1st search, given the setup done in main() def _do_best_first_search(start_node:str, paths:dict, scores:dict) -> None: # set up the open list (containing the start node) & the empty closed list open_list = PriorityQueue(False); open_list.add(start_node, scores[start_node]) closed_list = set() # main loop for a best-first search while not open_list.is_empty(): # check out the next node in the list active_node = open_list.get_next() if active_node in closed_list: continue closed_list.add(active_node) print("Exploring node " +active_node+ "... ", end="") # check to see if we found a goal (stop search if so) score = scores[active_node] if score == 0: print("GOAL!") break # add other nodes neighbors = paths[active_node] firstAdd = True for neighbor in neighbors: # handle output (skipping if already done) if neighbor in closed_list: continue if firstAdd: print("adding nodes " +neighbor, end="") else: print("," +neighbor, end="") firstAdd = False # actually add the neighbor to the open list open_list.add(neighbor, scores[neighbor]) # end this node if firstAdd: print("no neighboring nodes added") else: print() # the search is done--do final report if open_list.is_empty(): print("No path was found from node " + start_node + " to a goal node.") else: print("Upon termination, there were " +str(len(open_list))+ " nodes ready to explore: " + str(open_list)) # pseudo main() function if __name__ == "__main__": # test command-line args from sys import argv, exit, stderr if len(argv) != 2: print("Sorry--I need a graph file to explore.", file=stderr); exit(0) # load the file print('Loading file "' +argv[1]+ '".'); try: with open(argv[1]) as file: fileLines = [line.rstrip() for line in file] except FileNotFoundError: print('Sorry--couldn\'t find file "' +argv[1]+ '".', file=stderr) exit(0) # extact the needed data start_node = fileLines[0]; paths,scores = _extract_paths_and_scores(fileLines) # and do it!!!! _do_best_first_search(start_node, paths, scores)