Exemplo n.º 1
0
    def __init__(self, square_size=3, puzzle=None):
        self.square_size = square_size
        self.goal_block_location = self.in_order_goal_block_location
        self.goal_state = self.in_order_goal_state
        #self.heuristic = self.heuristic_misplaced  
        self.heuristic = self.heuristic_manhatten_distance

        self.puzzle = SliderPuzzle(self.square_size, puzzle)
Exemplo n.º 2
0
    def test_block_location(self):
        sp = SliderPuzzle(4)
        assert sp.current_block_location(15) == (3, 3)
        assert sp.current_block_location(0) == (0, 0)

        sp = SliderPuzzle(3, [8, 1, 2, 7, 4, 5, 6, 3, 0 ])
        assert sp.current_block_location(8) == (0, 0)
        assert sp.current_block_location(0) == (2, 2)
        assert sp.current_block_location(7) == (1, 0)
        assert sp.current_block_location(3) == (2, 1)
Exemplo n.º 3
0
    def test_possible_states(self):
        sp = SliderPuzzle(3)
        pm = sp.possible_moves()
        assert len(pm) == 2
        assert pm[0] == [ 1, 0, 2, 3, 4, 5, 6, 7, 8 ]
        assert pm[1] == [ 3, 1, 2, 0, 4, 5, 6, 7, 8 ]
        
        sp.puzzle = sp.swapped_state(0, 4)
        pm = sp.possible_moves()
        assert len(pm) == 4

        sp.puzzle = [4, 1, 2, 3, 0, 5, 6, 7, 8]
        exp_states = [
                        [4, 1, 2, 0, 3, 5, 6, 7, 8],
                        [4, 1, 2, 3, 5, 0, 6, 7, 8],
                        [4, 0, 2, 3, 1, 5, 6, 7, 8],
                        [4, 1, 2, 3, 7, 5, 6, 0, 8]
                        ]

        pm = sp.possible_moves()
        assert len(pm) == len(exp_states)
        for state in pm:
            assert state in exp_states
Exemplo n.º 4
0
    def test_tour(self):
        sp = SliderPuzzle(3)
        assert sp.puzzle == [0, 1, 2, 3, 4, 5, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 0, 2, 3, 4, 5, 6, 7, 8],
                [3, 1, 2, 0, 4, 5, 6, 7, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 1)
        assert sp.puzzle == [1, 0, 2, 3, 4, 5, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [0, 1, 2, 3, 4, 5, 6, 7, 8],
                [1, 2, 0, 3, 4, 5, 6, 7, 8],
                [1, 4, 2, 3, 0, 5, 6, 7, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 2)
        assert sp.puzzle == [1, 2, 0, 3, 4, 5, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 0, 2, 3, 4, 5, 6, 7, 8],
                [1, 2, 5, 3, 4, 0, 6, 7, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 5)
        assert sp.puzzle == [1, 2, 5, 3, 4, 0, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 2, 0, 3, 4, 5, 6, 7, 8],
                [1, 2, 5, 3, 0, 4, 6, 7, 8],
                [1, 2, 5, 3, 4, 8, 6, 7, 0]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 4)
        assert sp.puzzle == [1, 2, 5, 3, 0, 4, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 0, 5, 3, 2, 4, 6, 7, 8],
                [1, 2, 5, 3, 7, 4, 6, 0, 8],
                [1, 2, 5, 0, 3, 4, 6, 7, 8],
                [1, 2, 5, 3, 4, 0, 6, 7, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 3)
        assert sp.puzzle == [1, 2, 5, 0, 3, 4, 6, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [0, 2, 5, 1, 3, 4, 6, 7, 8],
                [1, 2, 5, 3, 0, 4, 6, 7, 8],
                [1, 2, 5, 6, 3, 4, 0, 7, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 6)
        assert sp.puzzle == [1, 2, 5, 6, 3, 4, 0, 7, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 2, 5, 0, 3, 4, 6, 7, 8],
                [1, 2, 5, 6, 3, 4, 7, 0, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 7)
        assert sp.puzzle == [1, 2, 5, 6, 3, 4, 7, 0, 8]
        ps = sp.possible_moves()
        exp_p = [
                [1, 2, 5, 6, 0, 4, 7, 3, 8],
                [1, 2, 5, 6, 3, 4, 0, 7, 8],
                [1, 2, 5, 6, 3, 4, 7, 8, 0]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps

        sp.puzzle = sp.swapped_blocks(0, 8)
        assert sp.puzzle == [1, 2, 5, 6, 3, 4, 7, 8, 0]
        ps = sp.possible_moves()
        exp_p = [
                [1, 2, 5, 6, 3, 0, 7, 8, 4],
                [1, 2, 5, 6, 3, 4, 7, 0, 8]
                ]
        assert len(ps) == len(exp_p)
        for state in exp_p:
            assert state in ps
Exemplo n.º 5
0
 def test_swap_state(self):
     sp = SliderPuzzle(3)
     swapped_sp = sp.swapped_state(0,8)
     assert swapped_sp[0] == 8
     assert swapped_sp[-1] == 0
Exemplo n.º 6
0
class SliderSearch(object):
    """
    Represents a searcher on SliderPuzzles
    """
    def __init__(self, square_size=3, puzzle=None):
        self.square_size = square_size
        self.goal_block_location = self.in_order_goal_block_location
        self.goal_state = self.in_order_goal_state
        #self.heuristic = self.heuristic_misplaced  
        self.heuristic = self.heuristic_manhatten_distance

        self.puzzle = SliderPuzzle(self.square_size, puzzle)

    def in_order_goal_block_location(self, block_number):
        """
        Gets the goal block location
        as a tuple (rowindex, columnindex)
        Assumes goal state is all values in order
        """
        return (block_number // self.square_size,
                block_number % self.square_size)

    def in_order_goal_state(self):
        """
        Gets the goal state for the puzzle
        when goal is all values in order
        """
        return [x for x in xrange(self.square_size**2)]

    def heuristic_misplaced(self, state):
        """
        Gets the heuristic value for the given state
        using a simple count of misplaced blocks
        """
        misplaced = 0
        for x in self.puzzle.puzzle:
            if self.goal_block_location(x) != self.puzzle.current_block_location(x, state):
                misplaced += 1
        return misplaced

    def heuristic_manhatten_distance(self, state):
        """
        Gets the heuristic value for the given state
        using manhatten distance
        """
        m_distances = [abs((self.puzzle.current_block_location(x, state)[0]
                            - self.goal_block_location(x)[0]))
                        + abs((self.puzzle.current_block_location(x, state)[1]
                            - self.goal_block_location(x)[1]))
                        for x in state]
        return sum(m_distances)

    def search_a_star(self):
        """
        Find best path solution using A*
        Returns the list of states from initial to goal
        or None if no solution possible
        """
        frontier = []
        explored = set()
        frontier_seen = {}
        goal = self.goal_state()

        initial = (self.heuristic(self.puzzle.puzzle),
                    0,
                    Node(self.puzzle.puzzle, None, 0))

        frontier_seen[str(initial[2].state)] = 0
        heapq.heappush(frontier, initial)

        while 1:
            if not frontier:
                return None
            else:
                # choose node
                sel_node = heapq.heappop(frontier)
                selected = sel_node[2]
                stsel = str(selected)
                if frontier_seen[stsel] <= sel_node[1]:
                    if (selected.state == goal):
                        path = []
                        while selected.parent is not None:
                            path.append(selected.state)
                            selected = selected.parent
                        path.append(selected.state)
                        path = path[::-1]
                        return path
                    else:
                        # Expand the node
                        self.puzzle.puzzle = selected.state
                        ps = self.puzzle.possible_moves()

                        for x in ps:
                            strx = str(x)
                            vx = (self.heuristic(x) + selected.path_cost+1,
                                        selected.path_cost+1,
                                        Node(x, selected, selected.path_cost+1))
                            if strx in frontier_seen:
                                if frontier_seen[strx] > vx[1]:
                                    heapq.heappush(frontier, vx)
                                    frontier_seen[strx] = vx[1]
                            elif vx not in explored:
                                heapq.heappush(frontier, vx)
                                frontier_seen[strx] = vx[1]
                        # Move checked into explored
                        explored.add(sel_node)