def choose_next_node(self): """ Calculate f(x) for each new generated node from open_list. Choose next node. :return: next node. """ for node in self.open_list: heuristic = Heuristic(current_node=node, final_node=self.final_node, heuristic=self.heuristic) h_score = heuristic.calculate() node.h = h_score node.f = self.get_f_score(h_score, node) # sort list of node by f-score, from higher to lower. self.open_list.sort(key=lambda x: x.f) if len(self.open_list) > 1 and self.open_list[0].f == self.open_list[1].f: return [node for node in self.open_list if node.f == self.open_list[0].f] else: self.solution_history.append(deepcopy(self.open_list[0])) return self.open_list[0]
def play_AStar(self): start = time() rootNode = deepcopy(self.board) generatedNodes, repeatedNodes = 1, 0 if not rootNode.get_stor_coordinates(): end = time() return 'THERE ARE NO STORAGE LOCATIONS!', (end - start) if not rootNode.get_box_coordinates(): end = time() return 'THERE ARE NO BOX LOCATIONS!', (end - start) if not rootNode.get_player_loc(): end = time() return 'SOKOBAN PLAYER MISSING!', (end - start) if rootNode.is_goal_state(): end = time() return 'BOARD IS ALREADY IN GOAL STATE!', (end - start) H = Heuristic() # H.set_heuristic("manhattan2") heuristicVal = H.calculate(rootNode.get_stor_coordinates(), rootNode.get_box_coordinates()) frontier1 = PriorityQueue() frontier2 = PriorityQueue() path = PriorityQueue() frontier1.push(rootNode, heuristicVal) frontier2.push( (rootNode.get_player_loc(), rootNode.get_box_coordinates()), heuristicVal) path.push([''], heuristicVal) visited = [] deadlockConditions = 0 # Hamza: This i represents the number of states visited, I think generated Nodes does not apply because # we don't explore possible moves for all of the generated nodes so the branching factor cannot use this value # i, b = 0, 0 # don't really need i since we can just do len(visited) for this b = 0 self.branchingFactor = 0 self.treeDepth = 0 while True: # print('Generated Nodes: {}, Repeated Nodes: {}, Frontier Length: {}, Deadlock Conditions: {}'.format( # generatedNodes, repeatedNodes, len(frontier1.Heap), deadlockConditions)) if not frontier1.Heap: end = time() return 'SOLUTION NOT FOUND', (end - start) currentNode = frontier1.pop() (currentPlayer, currentBoxCoordinates) = frontier2.pop() currentActionSequence = path.pop() possibleMoves = currentNode.possible_moves() visited.append((currentPlayer, currentBoxCoordinates)) # Tree depth and branch factor variables b += len(possibleMoves) # branching factor of the current node # i = len(visited) # number of visited nodes self.treeDepth += 1 for move in possibleMoves: childNode = deepcopy(currentNode) generatedNodes += 1 childNode.update_board(move) if (childNode.get_player_loc(), childNode.get_box_coordinates()) not in visited: if childNode.is_goal_state(): childNode.make_board_grid() # childNode.display_board() end = time() self.branchingFactor = ceil( b / len(visited)) # average branching factor return str( len(currentActionSequence[1:] + [move]) ) + ' ' + ' '.join( map(lambda x: x.upper(), currentActionSequence[1:] + [move])).replace( ',', '') #, str((end - start)) + ' seconds' # return None if self.is_deadlock(childNode): # print('DEADLOCK CONDITION') deadlockConditions += 1 continue heuristicVal = H.calculate( childNode.get_stor_coordinates(), childNode.get_box_coordinates()) cost = self.compute_cost(currentActionSequence + [move]) # childNode.make_board_grid() # childNode.display_board() frontier1.push(childNode, heuristicVal + cost) frontier2.push((childNode.get_player_loc(), childNode.get_box_coordinates()), heuristicVal + cost) path.push(currentActionSequence + [move], heuristicVal + cost) else: repeatedNodes += 1