def test_iterable_becomes_attribute_if_passed_as_argument(eh):
    """An iterable in our case is limited to list, tuple."""
    from binary_heap import BinaryHeap
    b = BinaryHeap([1, 2, 3])
    c = BinaryHeap((1, 2, 3))
    assert type(b.iterable) == list
    assert type(c.iterable) == tuple
Beispiel #2
0
 def test_binary_heap_push(self):
     bh = BinaryHeap()
     self.assertEqual(bh.size(), 0)
     bh.push(1)
     bh.push(2)
     bh.push(3)
     self.assertEqual(bh.size(), 3)
Beispiel #3
0
 def test_binary_heap_max(self):
     bh = BinaryHeap()
     bh.push(1)
     bh.push(3)
     bh.push(2)
     self.assertEqual(bh.max(), 3)
     self.assertEqual(bh.size(), 3)
def shorted_path(G, src):
    dist = {}
    pred = {}

    n = 0
    infinity = sys.maxint

    for v in G.keys():
        dist[v] = infinity
        pred[v] = None
        n +=1

    dist[src] = 0
    bh = BinaryHeap(n, src, infinity)

    while not bh.isEmpty():
        u = bh.pop()
        for v, w in G[u]:
            newLen = dist[u] + w
            if newLen < dist[v]:
                dist[v] = newLen
                bh.decreaseKey(v, newLen)
                pred[v] = u

    return dist, pred
def test_unique_values_raises_error_if_1_value_in_list():
    """If a value is pushed into heap that already exists, error is raised."""
    from binary_heap import BinaryHeap
    b = BinaryHeap()
    b.push(1)
    with pytest.raises(ValueError):
        b.push(1)
Beispiel #6
0
def test_heap_delete_min_build_heap(benchmark, dsa_, values):
    nums = deepcopy(values)
    dsa_obj = BinaryHeap()
    dsa_obj.build_heap(values)
    to_del = values[len(values) // 2]

    benchmark(dsa_obj.delete_min)
Beispiel #7
0
def test_pop():
    bt = BinaryHeap()
    for i in range(50):
        bt.push(random.randint(0,1000))

    for i in range(49):
        tmp = max(bt._list[1:])
        bt.pop()
        assert  tmp == bt._list[0]
    bt.pop()
    assert 0 == len(bt._list)

    # testing for empty list pop
    a = BinaryHeap()
    with pytest.raises(IndexError):
        assert a.pop()
Beispiel #8
0
def least_cost_path(graph, start, dest, cost):
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance((edge[1], nbr)))
    # if the dest is not in reached, then no route was found
    if dest not in reached:
        return []

    current = dest
    route = [current]
    # go through the reached vertices until we get back to start and append
    # each vertice that we "stop" at
    while current != start:
        current = reached[current]
        route.append(current)
    # reverse the list because we made a list that went from the dest to start
    route = route[::-1]
    return route
Beispiel #9
0
    def __init__(self, width, length, height):
        """
        Generates all maze cells and edges
        """
        self.width = width
        self.length = length
        self.height = height
        self.generated = False
        self.graph = Graph((width, length, height))

        self.edge_queue = BinaryHeap()
        self.edges_added = 0
        self.inter_layer_edges = 0

        for x in range(width):
            for y in range(length):
                for z in range(height):
                    self.graph.add_vertex((x, y, z))

        self.areas = UnionFind([cell.get_pos() for cell in self])
        self.edge_choices = RandomSet(self.graph.get_all_edges())
        self.queue_factor = len(self.edge_choices) // LAYER_FACTOR

        for _ in range(self.queue_factor):
            edge = self.edge_choices.pop_random()
            self._queue_edge(edge)

        self.player = self.graph.get_cell((0, 0, 0))

        self.end_cell = self.graph.get_cell(
            (self.width - 1, self.length - 1, self.height - 1))
        self.end_cell.is_end = True
Beispiel #10
0
 def test_update_with_lower_value_for_leaf_node(self):
     values = [1, 3, 5, 7, 9, 10, 11]
     names = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
     binary_heap = BinaryHeap(self.setup(names, values))
     binary_heap.build_heap()
     binary_heap.update(6, 4)
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [1, 3, 4, 7, 9, 5, 11])
Beispiel #11
0
 def test_delete_min(self):
     names = ['A', 'B', 'C', 'D', 'E', 'F', 'G']
     values = [5, 3, 7, 1, 9, 10, 11]
     binary_heap = BinaryHeap(self.setup(names, values))
     binary_heap.build_heap()
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [1, 3, 7, 5, 9, 10, 11])
     self.assertEqual(binary_heap.delete_min().get_value_attribute(), 1)
Beispiel #12
0
def test_init_max():
    #TEST for MAX
    a = BinaryHeap("max",*[random.randint(0,100) for i in range(37)])
    index = a._size - 1
    while index :
        assert a._list[index] <= a._list[(index-1)//2]
        index -= 1
Beispiel #13
0
    def __init__(self, iterable=()):
        """Initialize a priority queue, optionally with items from iterable.

        The items in the priority queue are stored in a binary minheap. Items
        are first sorted by priority, then queue insertion order. Priority is
        expressed as an integer with 0 being the most important.

        args:
            iterable: an optional iterable to add to the priority queue. Items
                      added this way will be given a priority of None.

        each item inside iterable can be either:
        * A QNode object
        * A container with value, priority
        * A non-iterable value

        """
        self.heap = BinaryHeap(iterable=())
        for item in iterable:
            try:
                is_container = len(item) == 2
            except TypeError:  # Case of QNode or non-iterable item
                self.insert(item)
            else:
                if is_container:  # Case of value, iterable
                    self.insert(item[0], item[1])
                else:
                    raise TypeError(
                        "More than two args: instantiation supports\
                                 non-iter value or iter of value, priority")
Beispiel #14
0
def least_cost_path(graph, start, dest, cost):
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance(
                    (edge[1], nbr)))

    if dest not in reached:
        return []

    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]
    return path
Beispiel #15
0
 def test_insert(self):
     bh = BinaryHeap(compare=lambda a, b: a < b)
     bh.insert(3)
     bh.insert(3)
     bh.insert(2)
     self.assertSequenceEqual([3, 3, 2], bh.values)
     bh.insert(4)
     self.assertSequenceEqual([4, 3, 2, 3], bh.values)
Beispiel #16
0
 def test_correctness(self):
     for case in cases:
         bheap = BinaryHeap()
         bheap.build_heap(case)
         retrieved = []
         while len(bheap) > 0:
             retrieved.append(bheap.delete_min())
         self.assertEqual(retrieved, sorted(case))
Beispiel #17
0
 def test_insert_nodes_with_descending_values(self):
     binary_heap = BinaryHeap()
     binary_heap.insert(HeapNode({'name': 'A', 'value': 0.91}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.91])
     binary_heap.insert(HeapNode({'name': 'B', 'value': 0.57}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.57, 0.91])
     binary_heap.insert(HeapNode({'name': 'B', 'value': 0.34}, 'value'))
     self.assertEqual([x.get_value_attribute() for x in binary_heap.node_list if x is not None], [0.34, 0.91, 0.57])
Beispiel #18
0
def least_cost_path(graph, start, dest, location):
    """
    *** NOTE: This function is a modified version of our previous ***
    *** implementation of Dijkstra's Algorithm from Assignment 1  ***
    *** Part 1. Comments in code indicate changes made.           ***

    Find and return a least cost path in graph from start vertex to dest vertex.

    Args:
    graph (Graph): The digraph defining the edges between the
    vertices.
    start: The vertex where the path starts. It is assumed
    that start is a vertex of graph.
    dest: The vertex where the path ends. It is assumed
    that dest is a vertex of graph.
    location: A dictionary containing all the vertices on the screen.
    Keys of location are identifiers holding the vertices as values.

    Returns:
    list: A potentially empty list (if no path can be found) of
    the vertices in the graph. If there was a path, the first
    vertex is always start, the last is always dest in the list.
    Any two consecutive vertices correspond to some edge in graph.
    """

    reached = {}
    events = BinaryHeap()
    events.insert((start, start), 0)

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]

            # each vertex in our graph is a tuple, so we use tuples to find neighbours
            # instead of single values to find the neighbours of a vertex
            for nbr in graph.neighbours(location[edge[1]]):
                # find the identifier/key value attached to nbr tuple
                nbrID = neighbour_identifier(nbr, location)
                # insert to binary heap appropriately
                events.insert((edge[1], nbrID),
                              time + distance(location[edge[1]], nbr))

    # FIND MINIMUM PATH IF POSSIBLE
    if dest not in reached:
        return []

    # start at the dest and continously ind the parent of current vertex
    # until have reached starting vertex
    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]  # reverse the list so starts from the ghost
    return path
Beispiel #19
0
    def test_build_heap_extract_all_elements_should_return_sorted_elements(self):
        nums = [3, 4, -1, 15, 2, 77, -3, 4, 12]
        heap = BinaryHeap(nums)
        result = []
        expected = [77, 15, 12, 4, 4, 3, 2, -1, -3]
        while len(heap) > 0:
            result.append(heap.extract_max())

        self.assertEqual(result, expected)
Beispiel #20
0
def test_push():
    for x in range(50):
        a = BinaryHeap()
        for i in range(47):
            a.push(random.randint(0,100))
        assert max(a._list) == a._list[0]
    index = a._size - 1
    while index :
        assert a._list[index] <= a._list[(index-1)//2]
        index -= 1
def test_pop_returns_sorted_values():
    """Test pop entire bin returns sorted values."""
    from binary_heap import BinaryHeap
    import random
    rand_nums = list(set([random.randint(0, 1000000000)
                          for i in range(10000)]))
    b = BinaryHeap(rand_nums)
    # import pdb; pdb.set_trace()
    all_popped = [b.pop() for i in range(1, len(b.heap))]
    assert all_popped == sorted(rand_nums, reverse=True)
Beispiel #22
0
    def test_empty_heap_insert_extract_elements_should_return_sorted_elements(self):
        nums = [3, 4, -1, 15, 2, 77, -3, 4, 12]
        heap = BinaryHeap()
        expected = [77, 15, 12, 4, 4, 3, 2, -1, -3]
        result = []
        for num in nums:
            heap.insert(num)
        while heap.count > 0:
            result.append(heap.extract_max())

        self.assertEqual(result, expected)
Beispiel #23
0
    def least_cost_path_lrt(self, lrts, end):
        reached = {}
        events = BinaryHeap()

        #insert start location with time of 0 into the heap
        counter = 0
        for key, val in lrts.items():
            events.insert((val, val, 0), 0)

        while (len(events)) > 0:
            pair, time = events.popmin()
            #print(time)

            #account for heuristic so it is not compounded
            if (pair[2]):
                time -= pair[2]

            if pair[1] not in reached:
                # add to reached dictionary
                reached[pair[1]] = pair[0]

                #consider neighbors around each point and distance to each neighbor
                for neighbour in self.graph.neighbours(pair[1]):
                    point1 = self.locations[pair[1]]
                    point2 = self.locations[neighbour]

                    # maybe we could save distances between objects in a dict, and reuse them?

                    # add heuristic in for the form of euclidean distance. This will helps lead the searching algorithm
                    # more towards the end location

                    heuristic = euclidean_distance(point2, self.locations[end])

                    # add key and val to BinaryHeap called events
                    events.insert(
                        (pair[1], neighbour, heuristic),
                        time + euclidean_distance(point1, point2) + heuristic)

            # end loop right after destination is popped
            if (pair[1] == end):
                break

        # use the get_path included with the breadth_first_search helper file to find path from reached dictionary
        path = None
        closestLRT = None
        for key, val in lrts.items():
            if val in reached:
                path = get_path(reached, val, end)
            if path == None:
                pass
            else:
                closestLRT = key
                break
        return path, closestLRT
Beispiel #24
0
def heap_sort(arr):
    '''
    This consists of 2 steps:
    1. build a min heap, which is O(nlogn)
    2. extract all n elements of the heap, which is O(nlogn)
    Overall, this takes O(nlogn)
    '''
    heap = BinaryHeap(arr)
    result = []
    while not heap.is_empty():
        result.append(heap.extract_min())
    return result
def merge_list_using_heap(list1, list2, len_list1, len_list2):
    heap_instance = BinaryHeap()
    heap_instance.buildHeap(list2)
    for i in range(len_list1):
        if list1[i] > heap_instance.heaplist[0]:
            list1[i], heap_instance.heaplist[0] = heap_instance.heaplist[
                0], list1[i]
            heap_instance.shiftDown(0)
    heap_instance.inplace_sort()
    sorted_list = heap_instance.getHeap()
    sorted_list.reverse()
    print(list1 + sorted_list)
    return
Beispiel #26
0
def least_cost_path(graph, start, dest, cost):
    """Find and return a least cost path in graph from start vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
      O( E log(E) ).
    Args:
      graph (Graph): The digraph defining the edges between the
        vertices.
      start: The vertex where the path starts. It is assumed
        that start is a vertex of graph.
      dest:  The vertex where the path ends. It is assumed
        that dest is a vertex of graph.
      cost:  A class with a method called "distance" that takes
        as input an edge (a pair of vertices) and returns the cost
        of the edge. For more details, see the CostDistance class
        description below.
    Returns:
      list: A potentially empty list (if no path can be found) of
        the vertices in the graph. If there was a path, the first
        vertex is always start, the last is always dest in the list.
        Any two consecutive vertices correspond to some
        edge in graph.
        """

    reached = {} # empty dictionary
    events = BinaryHeap() # empty heap
    events.insert((start, start), 0) # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0] # burn vertex v, record predecessor u
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance((edge[1], nbr)))

    # if the dest is not in the reached dictionary, then return an empty list
    if dest not in reached:
      return []

    # IMPLEMENTED FROM GET_PATH FUNCTION FROM breadth_first_search
    # finds minimum path
    # start at the dest and continuosly and find the parent of current vertex
    # until have reached starting vertex
    current = dest
    path = [current]

    while current != start:
        current = reached[current]
        path.append(current)

    path = path[::-1]
    return path
Beispiel #27
0
def least_cost_path(graph, start, dest, cost):
    # Implementation of Dijkstra's algorithm
    events = BinaryHeap()
    reached = dict()
    events.insert((start, start), 0)  # Begin at time 0, at the start vertex

    while events:
        edge, time = events.popmin()  # Get next burnt vertex
        if edge[1] not in reached:  # If the destination is not been reached
            reached[edge[1]] = edge[0]  # Keep track of where we came from
            for w in graph.neighbours(edge[1]):  # Burn the neighbours!!!!
                events.insert(((edge[1]), w), (time + cost.distance(
                    (edge[1], w))))  # Add the fuse

    return get_path(reached, start, dest)  # return the path
def kruskal(V, E, W):
    ds = DisjointSets()
    min_weight_priority = MinEdgePriority(W)
    heap = BinaryHeap(min_weight_priority)
    A = []
    for v in V:
        ds.make_set(v)
    for e in E:
        heap.insert(e)
    while not heap.is_empty():
        (u, v) = heap.extract()
        if ds.find_set(u) != ds.find_set(v):
            A.append((u, v))
            ds.union(u, v)
    return A
Beispiel #29
0
def least_cost_path(graph, start, dest, cost):
    """Find and return a least cost path in graph from start
    vertex to dest vertex.
    Efficiency: If E is the number of edges, the run-time is
    O( E log(E) ).
    Args:
    graph (Graph): The digraph defining the edges between the
    vertices.
    start: The vertex where the path starts. It is assumed
    that start is a vertex of graph.
    dest:  The vertex where the path ends. It is assumed
    that dest is a vertex of graph.
    cost:  A class with a method called "distance" that takes
    as input an edge (a pair of vertices) and returns the cost
    of the edge. For more details, see the CostDistance class
    description below.
    Returns:
    list: A potentially empty list (if no path can be found) of
    the vertices in the graph. If there was a path, the first
    vertex is always start, the last is always dest in the list.
    Any two consecutive vertices correspond to some
    edge in graph.
    """
    reached = {}  # empty dictionary
    events = BinaryHeap()  # empty heap
    events.insert((start, start), 0)  # vertex s burns at time 0

    while len(events) > 0:
        edge, time = events.popmin()
        if edge[1] not in reached:
            reached[edge[1]] = edge[0]
            for nbr in graph.neighbours(edge[1]):
                events.insert((edge[1], nbr), time + cost.distance(
                    (edge[1], nbr)))
    # if the dest is not in reached, then no route was found
    if dest not in reached:
        return []

    current = dest
    route = [current]
    # go through the reached vertices until we get back to start and append
    # each vertice that we "stop" at
    while current != start:
        current = reached[current]
        route.append(current)
    # reverse the list because we made a list that went from the dest to start
    route = route[::-1]
    return route
Beispiel #30
0
def a_star(G: Graph, start: int, stop: int):
    H = G.H
    open = BinaryHeap()
    for succ in G.get_succesors(start):
        open.add([G[start][succ] + H[succ][stop], start, succ])
    closed = Map(start, len(G))
    while True:
        f, u, x = open.get()
        g = f - H[x][stop]
        if g < closed[x][0]:
            closed[x] = (round(g, 2), u)
            for ng in G.get_succesors(x):
                if ng not in closed:
                    open.add((closed[x][0] + G[x][ng] + H[ng][stop], x, ng))
        if x == stop:
            return closed.reconstruct_path(start, stop)