Example #1
0
def test_empty_heap_creation():
    heap = IndexedHeap()
    assert len(heap) == 0, 'The length should be equal to 0'
    assert len(heap) == len(
        list(heap),
    ), 'The length should be exact as the number of the stored elements'
    assert heap.pop_first() == (None, None), 'Pop oeration should return None'
Example #2
0
 def __init__(self, window_size=-1):
     self.window_size = window_size
     self.median = 0
     self.iter = 0
     self.history = deque() if window_size > 0 else None
     self.lower = IndexedHeap()
     self.upper = IndexedHeap()
Example #3
0
def test_heap_delete_item():
    heap = IndexedHeap({1: 4, 2: 2, 3: 3, 4: 1, 5: 5})

    del heap[3]
    assert 3 not in heap, 'Key `3` should not be in the heap'
    assert are_sorted_heaps_equal(
        heap,
        IndexedHeap({1: 4, 2: 2, 4: 1, 5: 5}),
    ), 'Two heaps should be equal'
Example #4
0
def test_heap_len():
    heap = IndexedHeap()
    assert len(heap) == 0, 'Length of empty heap should be equal to 0'
    assert len(heap) == len(
        list(heap),
    ), 'The length should be exact the number of the stored elements'

    heap = IndexedHeap({1: 'A', 2: 'B'})
    assert len(heap) == 2, 'Heap length should be equal to 2'
    assert len(heap) == len(
        list(heap),
    ), 'The length should be exact the number of the stored elements'
Example #5
0
def test_heap_update():
    test_values = {1: 'A', 2: 'B', 3: 'C'}

    heap = IndexedHeap()
    heap.update(test_values)
    assert are_sorted_heaps_equal(
        heap,
        IndexedHeap(test_values),
    ), 'Two heaps should be equal'

    heap.update(test_values)
    heap.update({3: 'X', 4: 'Z'})
    assert are_sorted_heaps_equal(
        heap,
        IndexedHeap({1: 'A', 2: 'B', 3: 'X', 4: 'Z'}),
    ), 'Two heaps should be equal'
Example #6
0
def test_heap_iterator():
    test_items = {1: 4, 2: 2, 3: 3, 4: 1, 5: 5}
    heap = IndexedHeap(test_items)

    assert set(heap) == set(
        test_items.items(),
    ), 'Iteration should be performed over all items in the heap'
Example #7
0
def test_heap_check_key():
    test_values = {1: 'A', 2: 'B', 3: 'C'}
    heap = IndexedHeap(test_values)

    assert all(
        key in heap for key in test_values
    ), 'In operator should provide valid results'

    assert 6 not in heap, 'Value with key 6 should not be found'
Example #8
0
def test_set_item_via_index():
    heap = IndexedHeap()
    heap[1] = 'A'
    heap[2] = 'B'
    heap[3] = 'C'
    assert are_sorted_heaps_equal(
        heap,
        IndexedHeap({1: 'A', 2: 'B', 3: 'C'}),
    ), 'Two heaps should be equal'

    heap[1] = 'A'
    heap[2] = 'B'
    heap[3] = 'C'
    heap[3] = 'X'
    assert are_sorted_heaps_equal(
        heap,
        IndexedHeap({1: 'A', 2: 'B', 3: 'X'}),
    ), 'Two heaps should be equal'
Example #9
0
def test_heap_reversed_order():
    test_values = {1: 4, 2: 2, 4: 1, 5: 5}
    heap = IndexedHeap(test_values, reverse=True)

    assert is_heap(
        list(heap),
        start_position=0,
        compare_fn=lambda first, second: first[1] >= second[1],
    ), 'Max heap should be created'

    assert (
        heap.pop_first(),
        heap.pop_first(),
        heap.pop_first(),
        heap.pop_first(),
    ) == (
        (5, 5), (1, 4), (2, 2), (4, 1)  
    ), 'The items should be poped in sorted order'
Example #10
0
def test_heap_get_item_via_index():
    test_values = {1: 4, 2: 2, 3: 3, 4: 1, 5: 5}

    heap = IndexedHeap(test_values)

    assert (
        heap[1], heap[2], heap[3], heap[4], heap[5],
    ) == (
        4, 2, 3, 1, 5,
    ), 'Items should be accessible via keys'
Example #11
0
def test_heap_default_order():
    test_values = {1: 4, 2: 2, 3: 3, 4: 1, 5: 5}

    heap = IndexedHeap(test_values)
    assert is_heap(
        list(heap),
        start_position=0,
        compare_fn=lambda first, second: first[1] <= second[1],
    ), 'Min heap should be created by default'

    assert (
        heap.pop_first(),
        heap.pop_first(),
        heap.pop_first(),
        heap.pop_first(),
        heap.pop_first(),
    ) == (
        (4, 1), (2, 2), (3, 3), (1, 4), (5, 5),
    ), 'The items should be poped in sorted order'
Example #12
0
def test_heap_update_item_key_decreased():
    heap = IndexedHeap({1: 4, 2: 2, 3: 3, 4: 1, 5: 5})
    heap[5] = 0

    assert is_heap(
        list(heap),
        start_position=0,
        compare_fn=lambda first, second: first[1] <= second[1],
    ), 'Min heap should be created by default'

    list(
        sort(heap),
    ) == [
        (5, 0), (4, 1), (2, 2), (3, 3), (1, 4),
    ], 'The items should be poped in sorted order'
Example #13
0
    def minimum_spanning_tree(self, root=0):
        """
        Implementacion del algoritmo de Prim.
        Da por sentado que esta instancia de Digrafo es un Grafo. Es decir, que
        una arista esta representada por dos aristas dirigidas del mismo peso.
        Inicia el algoritmo desde el vertice raiz "root", por defecto = 0.
        :return Digraph: arbol de tendido minimo dirigido
        """
        # Setup
        visited = [False] * self.V()
        # edge_to = {dstVertex: Edge(srcVertex, dstVertex, weight)}
        edge_to = {}
        # heap inicializado con vertice raiz del arbol
        heap = IndexedHeap()
        heap._push(root, 0)

        # Execution
        while heap:
            v = heap.pop()
            visited[v] = True

            for e in self.adj_e(v):
                if not visited[e.dst]:
                    new_priority = e.weight
                    if e.dst in heap:
                        if new_priority < heap[e.dst]:
                            edge_to[e.dst] = e
                            heap._decreaseKey(e.dst, new_priority)
                    else:
                        edge_to[e.dst] = e
                        heap._push(e.dst, new_priority)

        # Return
        tree = Digraph(self.V())
        for edge in edge_to.values():
            tree.add_edge(edge.src, edge.dst, edge.weight)
        return tree
Example #14
0
def test_heap_created_with_custom_key_second_value_used_as_key():
    class Value:
        def __init__(self, key):
            self.key = key

        def __eq__(self, other):
            return self.key == other.key

    heap = IndexedHeap(
        {
            1: Value(1),
            2: Value(2),
            3: Value(3),
            4: Value(4),
            5: Value(5),
        },
        key=lambda i: i.key,
    )

    assert is_heap(
        list(heap),
        start_position=0,
        compare_fn=lambda first, second: first[1].key <= second[1].key
    ), 'Min heap should be created by default'

    assert (
        heap[1], heap[2], heap[3], heap[4], heap[5],
    ) == (
        Value(1), Value(2), Value(3), Value(4), Value(5),
    ), 'Items should be accessible via keys'

    list(
        sort(heap),
    ) == [
        (1, Value(1)),
        (2, Value(2)),
        (3, Value(3)),
        (4, Value(4)),
        (5, Value(5)),
    ], 'The items should be poped in sorted order'
Example #15
0
def dijkstra_shortest_paths(adj_list, node_from, infinity_value=0xFFFFFFFF):
    distances = {k: infinity_value for k in get_nodes(adj_list)}
    distances[node_from] = 0

    visit_queue = IndexedHeap(distances)

    next_edge, distance = visit_queue.pop_first()
    while next_edge is not None:
        for edge in get_edges_from(adj_list, next_edge):
            if edge[0] in visit_queue and (distances[edge[0]] >
                                           distance + edge[1]):
                distances[edge[0]] = distance + edge[1]
                visit_queue.update({edge[0]: distances[edge[0]]})
        next_edge, distance = visit_queue.pop_first()

    return distances
Example #16
0
def test_utils_are_sorted_heaps_equal():
    heap1 = IndexedHeap({1: 'A', 2: 'B'})
    heap2 = IndexedHeap({1: 'C', 2: 'D'})

    assert not are_sorted_heaps_equal(heap1, heap2)
    assert not list(heap1)
    assert not list(heap2)

    assert are_sorted_heaps_equal(
        IndexedHeap({1: 'A', 2: 'B'}),
        IndexedHeap({1: 'A', 2: 'B'}),
    )

    assert are_sorted_heaps_equal(
        IndexedHeap(),
        IndexedHeap(),
    )
Example #17
0
def test_heap_sort():
    heap = IndexedHeap({1: 4, 2: 2, 3: 3, 4: 1, 5: 5})

    assert list(sort(heap)) == [(4, 1), (2, 2), (3, 3), (1, 4), (5, 5)]
Example #18
0
class MovingMedian:    
    def __init__(self, window_size=-1):
        self.window_size = window_size
        self.median = 0
        self.iter = 0
        self.history = deque() if window_size > 0 else None
        self.lower = IndexedHeap()
        self.upper = IndexedHeap()
        
    def update(self, v):                
        if not self.upper.size():
            self.upper.push((v, 0))
            if self.window_size > 0:
                self.history.append((v, 0))
            self.median = v
            return

        self.iter += 1

        if self.window_size > 0 and len(self.history) == self.window_size:
            oldest, i = self.history.popleft()
            if self.lower.has((-oldest, i)):
                self.lower.decrease((-oldest, i), (float('-inf'),) * 2)
                self.lower.pop()
            elif self.upper.has((oldest, i)):
                self.upper.decrease((oldest, i), (float('-inf'),) * 2)
                self.upper.pop()
            else:
                raise Exception('oldest value not found {}'.format(oldest))

        if v > self.upper.peek()[0]:
            self.upper.push((v, self.iter))
            if self.window_size > 0:
                self.history.append((v, self.iter))
        else:
            self.lower.push((-v, self.iter))
            if self.window_size > 0:
                self.history.append((v, self.iter))

        if self.upper.size() - self.lower.size() > 1:
            item = self.upper.pop()
            self.lower.push((-item[0], item[1]))

        if self.lower.size() - self.upper.size() > 1:
            item = self.lower.pop()
            self.upper.push((-item[0], item[1]))

        if self.upper.size() > self.lower.size():
            self.median = self.upper.peek()[0]
        elif self.lower.size() > self.upper.size():
            self.median = -self.lower.peek()[0]
        else:
            self.median = (-self.lower.peek()[0] + self.upper.peek()[0]) / 2.0