def aStar(source): global explored_num global produced_num # The open and closed sets openset = set() closedset = set() # Current point is the starting point start = Node(state=source, parent=None, depth=0) # Add the starting point to the open set openset.add(start) # While the open set is not empty while openset: # Find the item in the open set with the lowest G + H score node = min(openset, key=lambda o: o.g + o.h) explored_num += 1 # If it is the item we want, retrace the path and return it if node.is_goal(): print("goal depth = {}".format(node.depth)) cells = [] while node.parent is not None: state = node.state for pack in state: pack.reverse() cells.append(state) node = node.parent for pack in source: pack.reverse() cells.append(source) cells.reverse() return cells # Remove the item from the open set openset.remove(node) # Add it to the closed set closedset.add(node) # Loop through the node's children/siblings neighbors = list(neighbors_for_packs(node.state)) produced_num += len(neighbors) for neighbor_state in neighbors: neighbor = Node(state=neighbor_state, parent=node, depth=node.depth + 1) # If it is already in the closed set, skip it if neighbor in closedset: continue # Otherwise if it is already in the open set if neighbor in openset: # Check if we beat the G score new_g = node.g + 1 if neighbor.g > new_g: # If so, update the node to have a new parent neighbor.g = new_g neighbor.parent = node else: # If it isn't in the open set, calculate the G and H score for the node neighbor.g = node.g + 1 neighbor.h = heuristic(neighbor) neighbor.parent = node # Add it to the set openset.add(neighbor) # return None if there is no path return None