def solve(self): """ This method returns a sequence of actions that covers all target locations on the board. """ fringe = util.PriorityQueue() start_state = self.get_start_state() fringe.push(Node(start_state, None, None, 0), 0) closed = {} while not fringe.isEmpty(): current_node = fringe.pop() variations = self.state_symmetry(current_node.state) if self.is_goal_state(current_node.state): print('Reach Goal') return current_node.get_action_trace_back() elif all(closed.get(key) is None for key in variations.keys()): # only expand node if none of its variations (rotations and flips) were discovered yet successors = self.get_successors(current_node.state) for successor, action, step_cost in successors: cost_so_far = current_node.cost_so_far + step_cost fringe.push( Node(successor, action, current_node, cost_so_far), cost_so_far + self.heuristic(successor, self.targets) ) closed[list(variations.keys())[0]] = True print('Cannot solve the problem') return []
def astar_search(problem): node = Node(problem.initial) frontier = [] explored = set() h = problem.manhattanDist(node) g = node.path_cost f = h + g heapq.heappush(frontier, (h, node)) while frontier: node = heapq.heappop(frontier)[1] if problem.goal_test(node.state): print(node.solution()) return node explored.add(node.state) for child in node.expand(problem): h = problem.manhattanDist(child) g = node.path_cost + 1 f = g + h if child.state not in explored and child not in frontier: child.path_cost = g heapq.heappush(frontier, (f, child)) elif child in frontier and child.path_cost > g: new_child = child new_child.cost = g frontier.remove(child) heapq.heappush(frontier, (f, new_child)) return None
def hierarchical_search(problem, hierarchy): """ [Figure 11.5] 'Hierarchical Search, a Breadth First Search implementation of Hierarchical Forward Planning Search' The problem is a real-world prodlem defined by the problem class, and the hierarchy is a dictionary of HLA - refinements (see refinements generator for details) """ act = Node(problem.actions[0]) frontier = FIFOQueue() frontier.append(act) while(True): if not frontier: return None plan = frontier.pop() print(plan.state.name) hla = plan.state # first_or_null(plan) prefix = None if plan.parent: prefix = plan.parent.state.action # prefix, suffix = subseq(plan.state, hla) outcome = Problem.result(problem, prefix) if hla is None: if outcome.goal_test(): return plan.path() else: print("else") for sequence in Problem.refinements(hla, outcome, hierarchy): print("...") frontier.append(Node(plan.state, plan.parent, sequence))
def test_root_with_mock_problem_with_child_and_grandchild(self): try: root = Node.root(MockProblem()) child = Node(0, parent=root) grandchild = Node(2, parent=child) except RecursionError: self.fail(msg="Recursion problem.")
def best_first_search_tree(problem, f): """Search the nodes with the lowest f scores first. You specify the function f(node) that you want to minimize; for example, if f is a heuristic estimate to the goal, then we have greedy best first search; if f is node.depth then we have breadth-first search. There is a subtlety: the line "f = memoize(f, 'f')" means that the f values will be cached on the nodes as they are computed. So after doing a best first search you can examine the f values of the path returned.""" # print("he sido llamado") f = memoize(f, 'f') node = Node(problem.initial) frontier = PriorityQueue('min', f) frontier.append(node) # frontier.mostrar() # explored = set() while frontier: node = frontier.pop() if problem.goal_test(node.state): return node # explored.add(node.state) for child in node.expand(problem): frontier.append(child) '''if child.state not in explored and child not in frontier: frontier.append(child) elif child in frontier: if f(child) < frontier[child]: # mira si ya hay una forma de llegar q es mayor a la que encontre ahora? del frontier[child] frontier.append(child)''' return None
def simulated_annealing_plot(problem, values_for_schedule): """[Figure 4.5] CAUTION: This differs from the pseudocode as it returns a state instead of a Node.""" schedule = exp_schedule(values_for_schedule[0], values_for_schedule[1], values_for_schedule[2]) x = list() y = list() current = Node(problem.initial) for t in range(sys.maxsize): T = schedule(t) if T == 0: plt.scatter(x, y) plt.show() return current.state neighbors = current.expand(problem) if not neighbors: plt.scatter(x, y) plt.show() return current.state next_choice = random.choice(neighbors) delta_e = problem.value(next_choice.state) - problem.value( current.state) y.append(problem.value(current.state)) x.append(t) if delta_e > 0 or probability(np.exp(delta_e / T)): current = next_choice
def solve(self): """ This method should return a sequence of actions that covers all target locations on the board. This time we trade optimality for speed. Therefore, your agent should try and cover one target location at a time. Each time, aiming for the closest uncovered location. You may define helpful functions as you wish. """ t = 0 current = Node(self.get_start_state()) backtrace = [] while True: if t == self.n_iter - 1 or self.is_goal_state(current.state): return backtrace successors = self.get_successors(current.state) successors.sort(key=lambda successor: self.objective_function(successor[STATE_SUCCESSOR])) if len(successors) == 0: return backtrace best_score = self.objective_function(successors[0][STATE_SUCCESSOR]) best_successors = [successor for successor in successors if self.objective_function(successor[STATE_SUCCESSOR]) == best_score] successor = choice(best_successors) candidate = Node(successor[STATE_SUCCESSOR], parent=current, spawned_action=successor[MOVE_SUCCESSOR]) delta_e = self.objective_function(candidate.state) - self.objective_function(current.state) if delta_e < 0: current = candidate backtrace.append(current.spawned_action) t += 1
def bidirectional_breadth_first_search(problem, inverse_problem): frontier = [ (0, Node(problem.initial)), (1, Node(inverse_problem.initial)), ] explored = set() inverse_explored = set() while frontier: current = frontier.pop(0) prefix = current[0] current_node = current[1] if prefix == 0: if current_node in inverse_explored: return create_solution(current_node, [ node for node in inverse_explored if node.state == current_node.state ][0]) explored.add(current_node) frontier.extend( map(lambda node: (prefix, node), current_node.expand(problem))) else: if current_node in explored: return create_solution([ node for node in explored if node.state == current_node.state ][0], current_node) inverse_explored.add(current_node) frontier.extend( map(lambda node: (prefix, node), current_node.expand(inverse_problem))) return None
def instrumented_bidirectional_breadth_first_search(problem, inverse_problem, explored_nodes=False): frontier = [(1, Node(inverse_problem.initial)), (0, Node(problem.initial))] explored = set() inverse_explored = set() result = None while frontier: current = frontier.pop(0) prefix = current[0] current_node = current[1] if prefix == 0: if current_node in inverse_explored: result = create_solution(current_node, [ node for node in inverse_explored if node.state == current_node.state ][0]) break explored.add(current_node) frontier.extend( map(lambda node: (prefix, node), current_node.expand(problem))) else: if current_node in explored: result = create_solution([ node for node in explored if node.state == current_node.state ][0], current_node) break inverse_explored.add(current_node) frontier.extend( map(lambda node: (prefix, node), current_node.expand(inverse_problem))) if explored_nodes: return result, len(explored.union(inverse_explored)) return result
def my_best_first_graph_search(problem, f): """ Taken from Lab 3 Search the nodes with the lowest f scores first. You specify the function f(node) that you want to minimize; for example, if f is a heuristic estimate to the goal, then we have greedy best first search; if f is node.depth then we have breadth-first search. There is a subtlety: the line "f = memoize(f, 'f')" means that the f values will be cached on the nodes as they are computed. So after doing a best first search you can examine the f values of the path returned. """ # keep a track of the number of iterations for use in evaluation iterations = 0 f = memoize(f, 'f') node = Node(problem.initial) iterations += 1 # This is the goal state if problem.goal_test(node.state): iterations += 1 return (iterations, node) # Create a priority queue that is ordered by its distance # from the distance travelled so far (g) + the straight line distance # from the new node to the goal state (h) frontier = PriorityQueue('min', f) frontier.append(node) iterations += 1 explored = set() # Loop until there is no more nodes to visit while frontier: # Get the node with minimum f(n) = g(n) + h(n) node = frontier.pop() iterations += 1 # We have reached the goal, return the solution if problem.goal_test(node.state): iterations += 1 return iterations # Mark the node as visited explored.add(node.state) # Loop over the nodes neighbours and find the next node # with minimum f(n) for child in node.expand(problem): # Only consider new nodes which havent been explored yet # and the ones which we are about to explore in the # loop if child.state not in explored and child not in frontier: frontier.append(child) iterations += 1 # Update the new distance (f(n)) for this node # if it is smaller than the previous known one elif child in frontier: incumbent = frontier[child] if f(child) < f(incumbent): del frontier[incumbent] frontier.append(child) iterations += 1 iterations += 1 return iterations
def get_root(fen, moves): board = Board(fen) root = Node(fen) if moves is not None: for move in moves: fen = board.fen().split(' ') root.previous.append(' '.join(fen[:2])) board.push(Move.from_uci(move)) root.position = board.fen() return root
def simulated_annealing(problem, schedule=exp_schedule()): current = Node(problem.initial) for t in range(sys.maxsize): T = schedule(t) if T == 0: return current.state neighbors = current.expand(problem) if not neighbors: return current.state next = random.choice(neighbors) delta_e = problem.value(current.state) - problem.value(next.state) if delta_e > 0 or probability(math.exp(delta_e / T)): current = next
def best_first_tree_search(problem, f, display=False): # from search -- just modified to make it tree search f = memoize(f, 'f') node = Node(problem.initial) frontier = PriorityQueue('min', f) frontier.append(node) while frontier: node = frontier.pop() if problem.goal_test(node.state): return node for child in node.expand(problem): frontier.append(child) return None
def closest_location_search(problem, heuristic): """ An A* searc that uses the heuristic function that does not consider the path cost :param problem: ClosestLocationSearch :param heuristic: heuristic function :return: a list of actions to make to reach the goal """ queue = util.PriorityQueue() # Init the queue visited = set() actions = [] root = Node(problem.get_start_state()) h = heuristic(root.state, problem) - root.cost root.set_f(h) queue.push(root, root.f) while not queue.isEmpty(): # while queue is not empty node = queue.pop() while node.state in visited and not queue.isEmpty( ): # remove the same states from queue # with worse priority node = queue.pop() if problem.is_goal_state(node.state): actions = build_actions(node) return actions visited.add(node.state) for succ, act, cost in problem.get_successors( node.state): # Build successors if succ not in visited: new_node = Node(succ, act, node, cost) h = heuristic(new_node.state, problem) - new_node.cost new_node.set_f(h) # Update f(n) value queue.push(new_node, new_node.f) return actions
def main(): global default_cube global goal scrambled = scrambler(default, 3) cube = Rubiks(scrambled, goal) startTime = time.time() result = astar_search(cube) endTime = time.time() print('solution is', Node.solution(result)) print('path is', Node.path(result)) print('걸린 시간 :', endTime - startTime)
def solve(self): """ This method should return a sequence of actions that covers all target locations on the board. This time we trade optimality for speed. Therefore, your agent should try and cover one target location at a time. Each time, aiming for the closest uncovered location. You may define helpful functions as you wish. Probably a good way to start, would be something like this -- current_state = self.board.__copy__() backtrace = [] while .... actions = set of actions that covers the closets uncovered target location add actions to backtrace return backtrace """ fringe = util.PriorityQueue() start_state = self.get_start_state() fringe.push(Node(start_state, None, None, 0, params={'target': self.find_closest_target(start_state, self.starting_point)}), 0) closed = {} while not fringe.isEmpty(): current_node = fringe.pop() if self.is_goal_state(current_node.state): print('Reach Goal') return current_node.get_action_trace_back() if closed.get(current_node.state) is None: x, y = current_node.params['target'] successors = self.get_successors(current_node.state) for successor, action, step_cost in successors: cost_so_far = current_node.cost_so_far + step_cost successor_target = (x, y) if successor.get_position(y, x) != -1: successor_target = self.find_closest_target(successor, (x, y)) cost_so_far = step_cost if successor_target == (-1, -1): return current_node.get_action_trace_back() + [action] fringe.push( Node(successor, action, current_node, cost_so_far, params={'target': successor_target}), cost_so_far + self.heuristic(successor, successor_target) ) closed[current_node.state] = True print('Cannot solve the problem') return []
def test_get_grandparents_value(self): board2 = Board() node1 = Node(True, board2) node2 = node1.createChild() node3 = node2.createChild() node3.get_grandparents_value() node2.get_grandparents_value() self.assertEqual(node3.value, node1.value) self.assertNotEquals(node2.value, node1.value) node2.value = -10 node4 = node3.createChild() node4.get_grandparents_value() self.assertEqual(node4.value, -10)
def breadth_first_graph_search(problem): node = Node(problem.initial) if problem.goal_test(node.state): return node frontier = deque([node]) explored = set() while frontier: node = frontier.popleft() explored.add(node.state) for child in node.expand(problem): if child.state not in explored and child not in frontier: if problem.goal_test(child.state): print(child.solution()) return child frontier.append(child) return None
def graph_depth_limited_search(problem, limit=50): """[Figure 3.17]""" explored = [] def graph_recursive_dls(node, problem, limit, explored): if node.state in explored: return None else: explored.append(node.state) if problem.goal_test(node.state): return node elif limit == 0: return 'cutoff' else: cutoff_occurred = False for child in node.expand(problem): result = graph_recursive_dls(child, problem, limit - 1, explored) if result == 'cutoff': cutoff_occurred = True elif result is not None: return result return 'cutoff' if cutoff_occurred else None # Body of depth_limited_search: return graph_recursive_dls(Node(problem.initial), problem, limit, explored)
def __init__(self, initial_state, expand_node, goal_test): self.nodes = [Node(initial_state, None, None, 1, 1)] # Root Node self.expand_node = expand_node # Function that returns expansion of inputted node self.goal_test = goal_test self.hashes = {self.nodes[0].state_hash: True} self.queue = Queue() self.queue.make_queue(self.expand_node(self.nodes[0]))
def best_first_greedy_search(problem): node = Node(problem.initial) frontier = [] explored = set() h = problem.manhattanDist(node) heapq.heappush(frontier, (h, node)) while frontier: node = heapq.heappop(frontier)[1] if problem.goal_test(node.state): print(node.solution()) return node explored.add(node.state) for child in node.expand(problem): if child.state not in explored and child not in frontier: h = problem.manhattanDist(child) heapq.heappush(frontier, (h, child)) return None
def breadth_first_search_for_vis(problem): node = Node(problem.initial) reached = [] reached.append(node.state) if problem.goal_test(node.state): return (node, reached) frontier = deque([node]) explored = set() while frontier: node = frontier.popleft() explored.add(node.state) reached.append(node.state) for child in node.expand(problem): if child.state not in explored and child not in frontier: if problem.goal_test(child.state): return (child, reached) frontier.append(child) return (failure, reached)
def __best_first_graph_search(self, problem, f): """Search the nodes with the lowest f scores first. You specify the function f(node) that you want to minimize; for example, if f is a heuristic estimate to the goal, then we have greedy best first search; if f is node.depth then we have breadth-first search. There is a subtlety: the line "f = memoize(f, 'f')" means that the f values will be cached on the nodes as they are computed. So after doing a best first search you can examine the f values of the path returned.""" f = self.__memoize(f, 'f') node = Node(problem.initial) assert node != None and node.state != None if problem.goal_test(node.state): return node frontier = PriorityQueue(min, f) frontier.append(node) explored = set() step = 0 while frontier: step+=1 node = frontier.pop() assert node != None and node.state != None, "Estratto un nodo None" #print '---- CURRENT NODE ----' #print node.state if problem.goal_test(node.state): return node, len(explored)+1 explored.add(node.state) for child in node.expand(problem): assert child != None and child.state != None if child.state not in explored and child not in frontier: frontier.append(child) elif child in frontier: incumbent = frontier[child] if f(child) < f(incumbent): del frontier[incumbent] frontier.append(child) return None
def main(): global default_problem global goal global goal2 puzzle = EightPuzzle(default_problem, goal) startTime = time.time() result = depth_limited_search(puzzle, 30) #result = breadth_first_tree_search(puzzle) endTime = time.time() print('solution is ', Node.solution(result)) print('path is', Node.path(result)) print('걸린 시간 :', endTime - startTime)
def depth_first_tree_search_cycle_detection(problem): frontier = [Node(problem.initial) ] # Stack, with the initial state of the problem. while frontier: node = frontier.pop() if problem.goal_test(node.state): return node if not cycle(node): frontier.extend(node.expand(problem)) return None
def breadth_first_count_nodes_at_depth(problem, depth=28): node = Node(problem.initial) node_count = 1 frontier = FIFOQueue() explored = set() frontier.append(node) old_depth = 1 while frontier: node = frontier.pop() explored.add(node.state) if node.depth != old_depth: old_depth = node.depth print node.depth for child in node.expand(problem): if child.state not in explored and child not in frontier: if node.depth == depth + 1: return node_count if node.depth == depth: node_count += 1 frontier.append(child) return None
def best_first_search_for_vis(problem, f): f = memoize(f, 'f') node = Node(problem.initial) frontier = PriorityQueue('min', f) frontier.append(node) explored = set() reached = [] while frontier: node = frontier.pop() reached.append(node.state) if problem.goal_test(node.state): return (node, reached) explored.add(node.state) for child in node.expand(problem): if child.state not in explored and child not in frontier: frontier.append(child) elif child in frontier: if f(child) < frontier[child]: del frontier[child] frontier.append(child) return (failure, reached)
def test_put0(self): tree = Node() tree.put('abc') self.assertEqual(1, tree.children[0].children[1].children[2].count[0]) tree.put('abd') self.assertEqual(1, tree.children[0].children[1].children[3].count[0])
def test_expand_procedure(self): frontier = [Node(True, Board())] search.expand(frontier) self.assertEqual(len(frontier), 7) for node in frontier: self.assertFalse(node.isMaxNode) self.assertEqual(node.value, float("inf")) self.assertEqual(node.depth, 1) self.assertFalse(node.board.last_move_won()) search.expand(frontier) self.assertEqual(len(frontier), 13) self.assertFalse(node.board.last_move_won())
def depth_limited_search(problem, limit=50): """Depth-first search with a limit. Depth-first search always expands the deepest node in the current frontier of the search tree. We apply a limit to prevent the algorithm from failing on problems with infinitely deep paths. Limit defaults to 50. """ root = Node(problem.initial_state) return __recursive_dls(root, problem, limit)
def sarkissian_hw6_2(problem): node = Node(problem.initial) if problem.goal_test(node.state): return node # heuristic function = the node's straight line distance to the goal node + the node's path cost def h(_node): return problem.straight_line_distance(_node.state) + _node.path_cost frontier = NodePriorityQueue(h) frontier.push(node) visited = [] while len(frontier) > 0: # pop a node out of the queue (this will always be the node with the lowest hueristic) node = frontier.pop( )[1] # NodePriorityQueue.pop() returns a tuple = (heuristic(node), node) visited.append(node.state) # if that node is the goal node, return the solution if problem.goal_test(node.state): print(f"Nodes Visited: {len(visited)}") print(f"Distance Traveled: {node.path_cost} km") return [ (n.state.lower(), h(n)) for n in node.path() ] # returns a list of 2-tuples (node.state, heuristic(node)) # if that node isn't the goal node, add its children to the frontier if they haven't already been visited for child in node.expand(problem): if child.state not in visited: frontier.push(child) return "FAILED"