def test_min_max_doubly_sorted():
    dictionnary = Dictionnary(implementation='doubly_sorted')
    assert dictionnary.min() is None
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    dictionnary.insert(item_0)
    dictionnary.insert(item_1)
    dictionnary.insert(item_2)
    dictionnary.insert(item_3)
    assert dictionnary.min() is item_0
    assert dictionnary.max() is item_3
def test_min_max_balanced_tree():
    dictionnary = Dictionnary(implementation='balanced_tree')
    assert dictionnary.min() is None
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    dictionnary.insert(item_0)
    dictionnary.insert(item_1)
    dictionnary.insert(item_2)
    dictionnary.insert(item_3)
    assert dictionnary.min() is item_0
    assert dictionnary.max() is item_3
Beispiel #3
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
Beispiel #4
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
Beispiel #5
0
def test_find_root():
    heap = Heap()
    items = [KeyedItem(key=i) for i in range(10)]
    random_items = [item for item in items]
    random.shuffle(random_items)
    heap.heapify(random_items)
    assert heap.find_root() is items[0]
def test_primitives():
    dictionnary = Dictionnary()
    with pytest.raises(NotImplementedError):
        dictionnary.search(key=0)
    with pytest.raises(NotImplementedError):
        dictionnary.insert(KeyedItem(0, 0))
    with pytest.raises(NotImplementedError):
        dictionnary.delete(KeyedItem(0, 0))
    with pytest.raises(NotImplementedError):
        dictionnary.max()
    with pytest.raises(NotImplementedError):
        dictionnary.min()
    with pytest.raises(NotImplementedError):
        dictionnary.predecessor(KeyedItem(0, 0))
    with pytest.raises(NotImplementedError):
        dictionnary.successor(KeyedItem(0, 0))
Beispiel #7
0
def test_delete_last():
    heap = Heap()
    items = [KeyedItem(key=i) for i in range(10)]
    heap.heapify(items)
    heap.delete(items[9])
    for i in range(9):
        assert heap.extract_root() is items[i]
    assert heap.extract_root() is None
Beispiel #8
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()
def test_search_balanced_tree():
    dictionnary = Dictionnary(implementation='balanced_tree')
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    item_4 = KeyedItem(key=4, content=4)
    dictionnary.insert(item_0)
    assert dictionnary.search(key=0) is item_0
    dictionnary.insert(item_3)
    dictionnary.insert(item_1)
    dictionnary.insert(item_4)
    dictionnary.insert(item_2)
    assert dictionnary.search(key=0) is item_0
    assert dictionnary.search(key=1) is item_1
    assert dictionnary.search(key=2) is item_2
    assert dictionnary.search(key=3) is item_3
    assert dictionnary.search(key=4) is item_4
Beispiel #10
0
def test_construct_max_heap():
    heap = Heap(heaptype='max')
    items = [KeyedItem(key=i) for i in range(10)]
    random_items = [item for item in items]
    random.shuffle(random_items)
    heap.heapify(random_items)
    for i in range(10):
        assert heap.extract_root() is items[10 - i - 1]
    assert heap.extract_root() is None
def test_search_doubly_unsorted():
    dictionnary = Dictionnary(implementation='doubly_unsorted')
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    item_4 = KeyedItem(key=4, content=4)
    dictionnary.insert(item_0)
    assert dictionnary.search(key=0) is item_0
    dictionnary.insert(item_3)
    dictionnary.insert(item_1)
    dictionnary.insert(item_4)
    dictionnary.insert(item_2)
    assert dictionnary.search(key=0) is item_0
    assert dictionnary.search(key=1) is item_1
    assert dictionnary.search(key=2) is item_2
    assert dictionnary.search(key=3) is item_3
    assert dictionnary.search(key=4) is item_4
def test_predecessor_successor_balanced_tree():
    dictionnary = Dictionnary(implementation='balanced_tree')
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    dictionnary.insert(item_0)
    dictionnary.insert(item_1)
    dictionnary.insert(item_2)
    dictionnary.insert(item_3)
    assert dictionnary.predecessor(item_0) is None
    assert dictionnary.predecessor(item_1) is item_0
    assert dictionnary.predecessor(item_2) is item_1
    assert dictionnary.predecessor(item_3) is item_2
    assert dictionnary.successor(item_0) is item_1
    assert dictionnary.successor(item_1) is item_2
    assert dictionnary.successor(item_2) is item_3
    assert dictionnary.successor(item_3) is None
def test_delete_unsorted_array():
    dictionnary = Dictionnary(implementation='unsorted_array')
    item_0 = KeyedItem(key=0, content=0)
    item_1 = KeyedItem(key=1, content=1)
    item_2 = KeyedItem(key=2, content=2)
    item_3 = KeyedItem(key=3, content=3)
    dictionnary.insert(item_0)
    dictionnary.insert(item_1)
    dictionnary.insert(item_2)
    dictionnary.insert(item_3)
    dictionnary.delete(item_0)
    assert dictionnary.min() is item_1
    dictionnary.delete(item_1)
    assert dictionnary.min() is item_2
    dictionnary.delete(item_3)
    assert dictionnary.max() is item_2
    dictionnary.delete(item_2)
    assert dictionnary.min() is None
    assert dictionnary.max() is None
Beispiel #14
0
def test_delete_root():
    heap = Heap()
    items = [KeyedItem(key=i) for i in range(10)]
    random_items = [item for item in items]
    random.shuffle(random_items)
    heap.heapify(random_items)
    heap.delete(items[0])
    for i in range(1, 10):
        assert heap.extract_root() is items[i]
    assert heap.extract_root() is None
Beispiel #15
0
def test_insert_min_heap():
    heap = Heap()
    items = [KeyedItem(key=i) for i in range(10)]
    random_items = [item for item in items]
    random.shuffle(random_items)
    for item in random_items:
        heap.insert(item)
    for i in range(10):
        assert heap.extract_root() is items[i]
    assert heap.extract_root() is None
Beispiel #16
0
def test_delete_with_bubble_down():
    heap = Heap()
    items_keys = list(range(5)) + list(range(100, 112))
    items = [KeyedItem(key=i) for i in items_keys]
    heap.heapify(items)
    heap.delete(items[5])
    for i in range(17):
        if i != 5:
            root = heap.extract_root()
            assert root is items[i]
    assert heap.extract_root() is None
Beispiel #17
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
Beispiel #18
0
def test_delete_with_bubble_up():
    heap = Heap()
    items_keys = (list(range(2)) + [100] + list(range(2, 4)) +
                  list(range(101, 103)) + list(range(4, 8)) +
                  list(range(103, 107)) + list(range(8, 10)))
    items = [KeyedItem(key=i) for i in items_keys]
    heap.heapify(items)
    heap.delete(items[5])
    for i in range(2):
        assert heap.extract_root() is items[i]
    for i in range(3, 5):
        assert heap.extract_root() is items[i]
    for i in range(7, 11):
        assert heap.extract_root() is items[i]
    for i in range(15, 17):
        assert heap.extract_root() is items[i]
    assert heap.extract_root() is items[2]
    assert heap.extract_root() is items[6]
    for i in range(11, 15):
        assert heap.extract_root() is items[i]
    assert heap.extract_root() is None
def test_search_unsorted_array():
    dictionnary = Dictionnary(implementation='unsorted_array')
    item = KeyedItem(key=0, content=0)
    dictionnary.insert(item)
    assert dictionnary.search(key=0) is item
Beispiel #20
0
def test_delete_only_item():
    heap = Heap()
    item = KeyedItem(key=0)
    heap.insert(item)
    heap.delete(item)
    assert heap.extract_root() is None
def test_search_fail_doubly_sorted():
    dictionnary = Dictionnary(implementation='doubly_sorted')
    item = KeyedItem(key=0, content=0)
    dictionnary.insert(item)
    with pytest.raises(FileNotFoundError):
        dictionnary.search(key=1)
Beispiel #22
0
def run_dijkstra_algorithm(graph: Graph,
                           source: Vertex) -> NodeList:
    nb_processed_vertices = 1
    nb_vertices = graph.nb_vertices
    shortest_paths = NodeList(vertices=graph.adjacency_lists)

    # a list of vertices does the bookkeeping of keeping track
    # of which vertices are processed/unprocessed
    vertex_statuses = NodeList(vertices=graph.adjacency_lists,
                               default=False)

    class ItemContent:
        def __init__(self, vertex: Vertex, edge: Edge=None):
            self.vertex = vertex
            self.edge = edge

    class Path:
        def __init__(self, source: Vertex):
            self.source = source
            self.destination = None
            self.path_to_last_hop = None
            self.last_hop = None
            self.distance = None

        def build(self, path_to_last_hop, last_hop: Edge):
            if self.source is not path_to_last_hop.source:
                raise PathError
            if path_to_last_hop.destination is not last_hop.head:
                raise PathError
            self.path_to_last_hop = path_to_last_hop
            self.last_hop = last_hop
            self.destination = last_hop.tail
            self.distance = path_to_last_hop.distance + last_hop.weight

    # a heap contains all vertices not in the path
    # their keys are the min distance to the source vertex
    # initialization in O(n + m)
    heap = Heap(heaptype='min')
    for vertex in graph.adjacency_lists:
        shortest_paths[vertex] = Path(source=source)
        shortest_paths[vertex].distance = inf

    shortest_paths[source].destination = source
    shortest_paths[source].distance = 0

    for edgenode in graph.adjacency_lists[source].edgenodes:
        tail = edgenode.tail
        if edgenode.weight < 0:
            raise GraphTypeError
        if shortest_paths[tail].distance is not None and edgenode.weight < shortest_paths[tail].distance:
            shortest_paths[tail].destination = tail
            shortest_paths[tail].last_hop = edgenode.to_edge(head=source)
            shortest_paths[tail].distance = edgenode.weight

    vertex_items = []
    for vertex in graph.adjacency_lists:
        if vertex is not source:
            vertex_item = KeyedItem(key=shortest_paths[vertex].distance,
                                    content=ItemContent(vertex=vertex,
                                                        edge=shortest_paths[vertex].last_hop))
            vertex_items.append(vertex_item)
            vertex_statuses[vertex] = vertex_item

    heap.heapify(vertex_items)
    del vertex_items

    def update_heap(deleted_vertex: Vertex, distance_to_deleted_vertex: float):
        nonlocal graph, heap, vertex_statuses
        # update status
        vertex_statuses[deleted_vertex] = False
        # remove from the heap all vertices connected to
        # the deleted vertex
        for edgenode in graph.adjacency_lists[deleted_vertex].edgenodes:
            tail = edgenode.tail
            # check if the tail is in unprocessed vertices set
            vertex_item = vertex_statuses[tail]
            if vertex_item:
                distance = vertex_item.key
                vertex = vertex_item.content.vertex
                edge = vertex_item.content.edge
                # delete it from the heap
                heap.delete(vertex_item)
                # recompute its distance
                if edgenode.weight < 0:
                    raise GraphTypeError
                new_distance = distance_to_deleted_vertex + edgenode.weight
                if new_distance < distance:
                    distance = new_distance
                    edge = edgenode.to_edge(head=deleted_vertex)
                vertex_item.key = distance
                vertex_item.content = ItemContent(vertex=vertex, edge=edge)
                # insert it back into the heap
                heap.insert(vertex_item)

    while nb_processed_vertices < nb_vertices:
        # pick cheapest edge crossing the cut
        # from the graph shortest_path_tree = (processed_vertices, paths)
        # to the graph graph - shortest_path_tree
        heap_item = heap.extract_root()
        last_hop = heap_item.content.edge
        v = heap_item.content.vertex
        # add it to the path leading to v
        shortest_paths[v].build(path_to_last_hop=shortest_paths[last_hop.head],
                                last_hop=last_hop)
        # update nb_processed_vertices
        nb_processed_vertices += 1
        # update heap
        update_heap(deleted_vertex=v, distance_to_deleted_vertex=shortest_paths[v].distance)

    return shortest_paths
Beispiel #23
0
def test_max_heapsort():
    sorted_items = [KeyedItem(key=i) for i in range(99, -1, -1)]
    items = [item for item in sorted_items]
    random.shuffle(items)
    assert heapsort(items, order='max') == sorted_items
def test_search_fail_balanced_tree():
    dictionnary = Dictionnary(implementation='balanced_tree')
    item = KeyedItem(key=0, content=0)
    dictionnary.insert(item)
    with pytest.raises(FileNotFoundError):
        dictionnary.search(key=1)
Beispiel #25
0
def test_min_heapsort():
    sorted_items = [KeyedItem(key=i) for i in range(100)]
    items = [item for item in sorted_items]
    random.shuffle(items)
    assert heapsort(items) == sorted_items
def test_negative_numbers_countsort():
    sorted_items = [KeyedItem(key=i) for i in range(-100, 100)]
    items = [item for item in sorted_items]
    random.shuffle(items)
    assert countsort(items) == sorted_items