예제 #1
0
    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 []
예제 #2
0
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
예제 #3
0
 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))
예제 #4
0
 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.")
예제 #5
0
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
예제 #7
0
 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
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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
예제 #15
0
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)
예제 #16
0
    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 []
예제 #17
0
    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)
예제 #18
0
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
예제 #19
0
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]))
예제 #21
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)
예제 #23
0
    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
예제 #24
0
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)
예제 #25
0
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
예제 #26
0
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)
예제 #28
0
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
예제 #29
0
파일: search_test.py 프로젝트: qpzm/PS
    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])
예제 #30
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)
예제 #32
0
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"