예제 #1
0
def dijkstra(start, end, board):
    Node = namedtuple("Node", ["pos", "d", "p"])
    seen = {}
    q = PriorityQueue()

    q.add(Node(start, 0, None), 0)
    while (len(q) > 0):
        cur = q.pop()
        if (cur.pos in seen):
            continue

        seen[cur.pos] = {'d': cur.d, 'p': cur.p}

        #Terminate early if we find the end
        if (cur.pos == end):
            break

        neighbors = [
            tile for tile in adjacent_positions(cur.pos)
            if (tile == end or tile_is_empty(tile, board))
        ]
        for tile in neighbors:
            q.add(Node(tile, cur.d + 1, cur.pos), cur.d + 1)

    if (end not in seen):
        return None

    path = []
    current = end
    while (current is not None):
        path.insert(0, current)
        current = seen[current]['p']

    return path
예제 #2
0
 def setUp(self):
     self.priorityqueue = PriorityQueue()
     self.priorityqueue.add(5, 5)
     self.priorityqueue.add(4, 4)
     self.priorityqueue.add(3, 3)
     self.priorityqueue.add(2, 2)
     self.priorityqueue.add(1, 1)
예제 #3
0
def test_primitives():
    priority_queue = PriorityQueue()
    with pytest.raises(NotImplementedError):
        priority_queue.insert(KeyedItem(0, 0))
    with pytest.raises(NotImplementedError):
        priority_queue.find_min()
    with pytest.raises(NotImplementedError):
        priority_queue.delete_min()
예제 #4
0
    def dijkstra_shortest_path(self, start_vetex):
        """
        Find the shortest distance from a starting vertex to all other vertices.

        Keyword arguments:
        start_vertex -- a vertex object.

        Time complexity:
        O(VLogV + ELogV)

        Space complexity:
        O(V)
        """

        unvisited_queue = PriorityQueue(self.size, lambda el: el.distance,
                                        lambda el: el.data)

        # Set all vertices to a distance of infinity and a previous vertex
        # of None. Set the start_vertex's distance to 0.
        for vertex in self.adjacency_list:
            vertex.distance = float('inf')
            vertex.previous_vertex = None
            if vertex == start_vetex:
                vertex.distance = 0
            unvisited_queue.push(vertex)

        # Time complexity: O(V)
        while not unvisited_queue.is_empty():

            # Time complexity: O(LogV)
            current_vertex = unvisited_queue.pop()

            # Go through each of the current_vertex's adjacent vertices checking
            # to see if the path from the current vertex is shorter than the
            # previously found paths.
            # Time complexity: O(E)
            for adjacent_vertex in self.adjacency_list[current_vertex]:

                edge_weight = self.edge_weights[(current_vertex,
                                                 adjacent_vertex)]
                new_distance = current_vertex.distance + edge_weight

                # If a shorter path is found, update the adjacent vertex's distance
                # to the new distance and set it's previous pointer to the
                # current vertex.
                if new_distance < adjacent_vertex.distance:
                    adjacent_vertex.distance = new_distance
                    adjacent_vertex.previous_vertex = current_vertex

                    # Time complexity: O(LogV)
                    unvisited_queue.update_priority(adjacent_vertex)
예제 #5
0
def test_find_min_balanced_tree():
    priority_queue = PriorityQueue(implementation='balanced_tree')
    assert priority_queue.find_min() is None
    item_4 = KeyedItem(4, 4)
    item_2 = KeyedItem(2, 2)
    item_3 = KeyedItem(3, 3)
    item_1 = KeyedItem(1, 1)
    priority_queue.insert(item_4)
    assert priority_queue.find_min() is item_4
    priority_queue.insert(item_2)
    assert priority_queue.find_min() is item_2
    priority_queue.insert(item_3)
    assert priority_queue.find_min() is item_2
    priority_queue.insert(item_1)
    assert priority_queue.find_min() is item_1
예제 #6
0
def test_find_min_unsorted_array():
    priority_queue = PriorityQueue(implementation='unsorted_array')
    assert priority_queue.find_min() is None
    item_4 = KeyedItem(4, 4)
    item_2 = KeyedItem(2, 2)
    item_3 = KeyedItem(3, 3)
    item_1 = KeyedItem(1, 1)
    priority_queue.insert(item_4)
    assert priority_queue.find_min() is item_4
    priority_queue.insert(item_2)
    assert priority_queue.find_min() is item_2
    priority_queue.insert(item_3)
    assert priority_queue.find_min() is item_2
    priority_queue.insert(item_1)
    assert priority_queue.find_min() is item_1
예제 #7
0
def huffman(characters):
    """
    Huffman codes compress data.
    greedy algorithm, optimal substructure
    If we assign a 3 bit codeword to each character, it takes 300k bits to encode a 100k character file
    What if we use variable length codes?
    prefix codes => no codeword is also a prefix of another codeword.
    :param characters: list of characters
    :return:
    """
    n = len(characters)
    queue = PriorityQueue(characters)
    queue.build_min_heap()
    for i in range(0, n-1):
        new_node = Character()
        new_node.left = queue.heap_extract_min()
        new_node.right = queue.heap_extract_min()
        new_node.freq = new_node.left.freq + new_node.right.freq
        queue.min_heap_insert(new_node)

    return queue.heap_extract_min()
예제 #8
0
def test_delete_sorted_array():
    priority_queue = PriorityQueue(implementation='sorted_array')
    item_4 = KeyedItem(4, 4)
    item_2 = KeyedItem(2, 2)
    item_3 = KeyedItem(3, 3)
    item_1 = KeyedItem(1, 1)
    priority_queue.insert(item_4)
    priority_queue.insert(item_2)
    priority_queue.insert(item_3)
    priority_queue.insert(item_1)
    assert priority_queue.find_min() is item_1
    priority_queue.delete_min()
    assert priority_queue.find_min() is item_2
    priority_queue.delete_min()
    assert priority_queue.find_min() is item_3
    priority_queue.delete_min()
    assert priority_queue.find_min() is item_4
    priority_queue.delete_min()
    assert priority_queue.find_min() is None
    priority_queue.delete_min()
    assert priority_queue.find_min() is None
예제 #9
0
파일: search.py 프로젝트: brownlzw/Search
def astar(problem, heur):
    """
  Implement A* search.

  The given heuristic function will take in a state of the search problem
  and produce a real number

  Your implementation should be able to work with any heuristic, heur
  that is for the given search problem (but, of course, without a
  guarantee of optimality if heur is not admissible).
  """
    start = problem.get_start_state()
    pq = PriorityQueue(True)
    visited = {}
    cost = {}
    cur = start
    pq.push_with_priority(start, heur(start))
    visited[start] = None
    cost[start] = 0
    while not pq.is_empty():
        cur = pq.pop()
        cur_cost = cost[cur]
        if problem.is_goal_state(cur):
            break
        dict = problem.get_successors(cur)
        for state in dict:
            if state not in visited:
                pq.push_with_priority(state,
                                      cur_cost + dict[state] + heur(state))
                visited[state] = cur
                cost[state] = cur_cost + dict[state]
    path = []
    while cur is not None:
        path.append(cur)
        cur = visited[cur]
    path.reverse()
    print len(visited)
    return path
예제 #10
0
def a_star(start, end, board):
    Node = namedtuple("Node", ["pos", "d", "prev"])
    seen = {}
    q = PriorityQueue()

    q.add(Node(start, 0, None), manhattan(start, end))

    while (len(q) > 0):
        current = q.pop()

        if (current.pos in seen):
            continue

        seen[current.pos] = current.prev

        if (current.pos == end):
            break

        neighbors = [
            tile for tile in adjacent_positions(current.pos)
            if (tile == end or tile_is_empty(tile, board))
        ]
        for neighbor in neighbors:
            q.add(Node(neighbor, current.d + 1, current.pos),
                  current.d + 1 + manhattan(neighbor, end))

    if (end not in seen):
        return None

    path = []
    current = end
    while (current is not None):
        path.insert(0, current)
        current = seen[current]

    return path
예제 #11
0
    def create_path(self, dest, gamemap):

        if not gamemap.is_valid_pixel_pos(dest):
            return []

        if not self.can_traverse(dest, gamemap):
            dest = self.__find_traversable_point(dest, gamemap)

        def neighbors(point):
            neighbors = []
            for x in range(-1, 2):
                for y in range(-1, 2):
                    if (x * gamemapping.squ_width, y * gamemapping.squ_width
                        ) != (0, 0) and gamemap.is_valid_pixel_pos(
                            (point[0] + x * gamemapping.squ_width,
                             point[1] + y * gamemapping.squ_width)):
                        neighbors.append(
                            (point[0] + x * gamemapping.squ_width,
                             point[1] + y * gamemapping.squ_width))
            return neighbors

        def heuristic(point, dest):
            return math.sqrt((point[0] - dest[0])**2 + (point[1] - dest[1])**2)

        def collide_squ_width(a, b):
            return a[0] >= b[0] and a[1] >= b[1] and a[
                0] <= b[0] + gamemapping.squ_width and a[
                    1] <= b[1] + gamemapping.squ_width

        came_from = {}
        cost_so_far = {}
        start_point = (int(self.location[0]), int(self.location[1]))
        current_point = start_point

        came_from[start_point] = None
        cost_so_far[start_point] = 0

        frontier = PriorityQueue()
        frontier.put(start_point, 0)

        while not frontier.is_empty():
            # print("path finding...")
            current_point = frontier.pop()

            # print("current point = ", current_point, " dest = ", dest, " ", current_point == dest)

            if collide_squ_width(current_point, dest):
                break

            for neighbor in neighbors(current_point):
                # print("neighbor ", neighbor)
                new_cost = cost_so_far[current_point] + self.get_traverse_cost(
                    neighbor, gamemap)
                if (neighbor not in cost_so_far.keys() or new_cost <
                        cost_so_far[neighbor]) and self.can_traverse(
                            neighbor, gamemap):
                    cost_so_far[neighbor] = new_cost
                    priority = cost_so_far[neighbor] + heuristic(
                        neighbor, dest)
                    frontier.put(neighbor, priority)
                    came_from[neighbor] = current_point

            # rel_point = (gamemap.rect.x + current_point[0], gamemap.rect.y + current_point[1])
            # screen.set_at(rel_point, (0, 0, 0))
            # pygame.display.flip()

        if not collide_squ_width(current_point, dest):
            return []

        path = []
        while current_point != start_point:
            # print("path construction...")
            path.insert(0, current_point)
            current_point = came_from[current_point]

        return path