Beispiel #1
0
    def test_sort_on_one_element_list(self):
        list = [heap.HeapItem(1)]

        self.heap.sort_in_place(list)

        self.assertEqual([heap.HeapItem(1)], list)
        self.assertEqual(1, self.heap.size)
Beispiel #2
0
    def test_sort_on_sorted_two_element_list(self):
        list = [heap.HeapItem(2), heap.HeapItem(1)]

        self.heap.sort_in_place(list)

        self.assertEqual([heap.HeapItem(2), heap.HeapItem(1)], list)
        self.assertEqual(2, self.heap.size)
Beispiel #3
0
    def test_insert_on_empty_list(self):
        self.assertEqual(0, self.heap.size)
        self.assertEqual([], self.heap.elements)

        self.heap.insert(heap.HeapItem(1))

        self.assertEqual(1, self.heap.size)
        self.assertEqual([heap.HeapItem(1)], self.heap.elements)
Beispiel #4
0
 def test_change_priority_on_non_empty_list_with_exceeding_index(self):
     self.heap.build([
         heap.HeapItem(9),
         heap.HeapItem(5),
         heap.HeapItem(6),
         heap.HeapItem(2),
         heap.HeapItem(3)
     ])
     with self.assertRaisesRegex(IndexError, ''):
         self.heap.change_priority(self.heap.size, 1)
Beispiel #5
0
    def test_change_priority_on_one_element_list(self):
        self.heap.build([heap.HeapItem(9)])

        self.assertEqual(1, self.heap.size)
        self.assertEqual([heap.HeapItem(9)], self.heap.elements)

        self.heap.change_priority(0, 1)

        self.assertEqual(1, self.heap.size)
        self.assertEqual([heap.HeapItem(1)], self.heap.elements)
Beispiel #6
0
    def test_str_on_three_element_heap(self):
        self.heap.build([
            heap.HeapItem(1, 'datum1'),
            heap.HeapItem(2, 'datum2'),
            heap.HeapItem(3, 'datum3')
        ])

        self.assertEqual(
            '[[priority=3, datum=datum3], ' + '[priority=2, datum=datum2], ' +
            '[priority=1, datum=datum1]]', str(self.heap))
Beispiel #7
0
    def test_insert_on_one_element_list(self):
        self.heap.build([heap.HeapItem(2)])

        self.assertEqual(1, self.heap.size)
        self.assertEqual([heap.HeapItem(2)], self.heap.elements)

        self.heap.insert(heap.HeapItem(1))

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(1), heap.HeapItem(2)],
                         self.heap.elements)
Beispiel #8
0
    def test_repr_on_three_element_heap(self):
        self.heap.build([
            heap.HeapItem(1, 'datum1'),
            heap.HeapItem(2, 'datum2'),
            heap.HeapItem(3, 'datum3')
        ])

        self.assertEqual(
            '[mode=HeapMode.max, size=3, ' +
            'list=[[priority=3, datum=datum3], ' +
            '[priority=2, datum=datum2], ' + '[priority=1, datum=datum1]]]',
            repr(self.heap))
Beispiel #9
0
    def dijkstra_shortest_paths(self, graph, start):
        """
        Finds the shortest paths between nodes in a graph, which may
        represent, for example, road networks. It was conceived by computer
        scientist Edsger W. Dijkstra in 1956 and published three years later.
        """

        distance_map, predecessor_map = \
                                  self._create_distance_and_previous_maps(graph)

        distance_map[start] = 0

        priority_queue = heap.BinHeap(heap.HeapMode.min)
        for node, value in distance_map.items():
            priority_queue.insert(heap.HeapItem(value, node))

        while priority_queue.size > 0:
            min_item = priority_queue.extract()
            node = min_item.datum
            for neighbor in graph.neighbors(node):
                if self._relax(graph, distance_map, predecessor_map, node,
                               neighbor):
                    index = self._index_in_priority_queue(
                        priority_queue, neighbor)
                    edge_distance = (distance_map[node] + graph.weight(
                        (node, neighbor)))
                    priority_queue.change_priority(index, edge_distance)

        return distance_map, predecessor_map
Beispiel #10
0
    def test_constructor_with_priority_and_datum(self):
        priority = 123
        datum = 'datum'
        item = heap.HeapItem(priority, datum)

        self.assertEqual(priority, item.priority)
        self.assertEqual(datum, item.datum)
Beispiel #11
0
    def test_build_on_five_element_list(self):
        self.heap.build([
            heap.HeapItem(9),
            heap.HeapItem(5),
            heap.HeapItem(6),
            heap.HeapItem(2),
            heap.HeapItem(3)
        ])

        self.assertEqual(5, self.heap.size)
        self.assertEqual([
            heap.HeapItem(2),
            heap.HeapItem(3),
            heap.HeapItem(6),
            heap.HeapItem(5),
            heap.HeapItem(9)
        ], self.heap.elements)
Beispiel #12
0
    def prim(self, graph):
        """
        Given a connected undirected graph G = (V, E) with positive edge
        weights, computes a minimum spanning tree that consists of a subset
        of edges E′ ⊆ E of minimum total weight such that the graph (V, E′)
        is connected.

        Greedy Strategy: Repeatedly attach a node to the current tree by
        the next lightest edge.

        Note: The graph must be really connected undirected.
        """

        minimum_spanning_tree = Graph()

        if (len(graph.nodes()) == 0):
            return minimum_spanning_tree

        distance_map, predecessor_map = \
                                  self._create_distance_and_previous_maps(graph)

        # pick any initial node (the graph must be connected)
        start = next(iter(graph.nodes()))
        distance_map[start] = 0

        priority_queue = heap.BinHeap(heap.HeapMode.min)
        for node, value in distance_map.items():
            minimum_spanning_tree.add_node(node)

            priority_queue.insert(heap.HeapItem(value, node))

        while priority_queue.size > 0:
            min_item = priority_queue.extract()
            node = min_item.datum
            for neighbor in graph.neighbors(node):
                edge = (node, neighbor)
                edge_distance = graph.weight(edge)
                neighbor_index = self._index_in_priority_queue(
                    priority_queue, neighbor)
                if (neighbor_index != None
                        and distance_map[neighbor] > edge_distance):
                    distance_map[neighbor] = edge_distance

                    priority_queue.change_priority(neighbor_index,
                                                   edge_distance)

                    predecessor_map[neighbor] = node

        for node, value in predecessor_map.items():
            if value != None:
                edge = (value, node)
                edge_distance = graph.weight(edge)
                minimum_spanning_tree.add_undirected_edge(
                    value, node, edge_distance)

        return minimum_spanning_tree
Beispiel #13
0
    def test_sort_on_sorted_five_element_list(self):
        list = [
            heap.HeapItem(9),
            heap.HeapItem(8),
            heap.HeapItem(5),
            heap.HeapItem(4),
            heap.HeapItem(2)
        ]

        self.heap.sort_in_place(list)

        self.assertEqual([
            heap.HeapItem(9),
            heap.HeapItem(8),
            heap.HeapItem(5),
            heap.HeapItem(4),
            heap.HeapItem(2)
        ], list)
        self.assertEqual(5, self.heap.size)
Beispiel #14
0
    def test_insert_on_two_element_list(self):
        self.heap.build([heap.HeapItem(3), heap.HeapItem(2)])

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(3), heap.HeapItem(2)],
                         self.heap.elements)

        self.heap.insert(heap.HeapItem(4))

        self.assertEqual(3, self.heap.size)
        self.assertEqual(
            [heap.HeapItem(4),
             heap.HeapItem(2),
             heap.HeapItem(3)], self.heap.elements)
Beispiel #15
0
    def test_build_on_three_element_list_as_3_2_1(self):
        self.heap.build([heap.HeapItem(3), heap.HeapItem(2), heap.HeapItem(1)])

        self.assertEqual(3, self.heap.size)
        self.assertEqual(
            [heap.HeapItem(3),
             heap.HeapItem(2),
             heap.HeapItem(1)], self.heap.elements)
Beispiel #16
0
    def test_sort_on_unsorted_four_element_list(self):
        list = [
            heap.HeapItem(1),
            heap.HeapItem(2),
            heap.HeapItem(3),
            heap.HeapItem(4)
        ]

        self.heap.sort_in_place(list)

        self.assertEqual([
            heap.HeapItem(4),
            heap.HeapItem(3),
            heap.HeapItem(2),
            heap.HeapItem(1)
        ], list)
        self.assertEqual(4, self.heap.size)
Beispiel #17
0
    def test_build_on_three_element_list_as_2_1_3(self):
        data = [heap.HeapItem(2), heap.HeapItem(1), heap.HeapItem(3)]

        self.heap.build(data)

        self.assertEqual(3, self.heap.size)
        self.assertEqual(
            [heap.HeapItem(1),
             heap.HeapItem(2),
             heap.HeapItem(3)], self.heap.elements)
Beispiel #18
0
    def test_change_priority_on_two_element_list_without_sift(self):
        self.heap.build([heap.HeapItem(9), heap.HeapItem(6)])

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(6), heap.HeapItem(9)],
                         self.heap.elements)

        self.heap.change_priority(0, 1)

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(1), heap.HeapItem(9)],
                         self.heap.elements)

        self.heap.change_priority(1, 2)

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(1), heap.HeapItem(2)],
                         self.heap.elements)
Beispiel #19
0
    def test_change_priority_on_two_element_list_with_sift_down_up(self):
        self.heap.build([heap.HeapItem(9), heap.HeapItem(6)])

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(6), heap.HeapItem(9)],
                         self.heap.elements)

        self.heap.change_priority(0, 10)

        self.assertEqual(2, self.heap.size)
        self.assertEqual(
            [heap.HeapItem(9), heap.HeapItem(10)], self.heap.elements)

        self.heap.change_priority(1, 8)

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(8), heap.HeapItem(9)],
                         self.heap.elements)
Beispiel #20
0
    def kruskal(self, graph):
        """
        Given a connected undirected graph G = (V, E) with positive edge
        weights, computes a minimum spanning tree that consists of a subset
        of edges E′ ⊆ E of minimum total weight such that the graph (V, E′)
        is connected.

        Greedy Strategy: Repeatedly adds the next lightest edge if this
        doesn’t produce a cycle.

        Note: The graph does not have to be undirected.
        """

        minimum_spanning_tree = Graph()

        set = union_find.UnionFind()

        node_to_wrapper_node_map = {}
        priority_queue = heap.BinHeap(heap.HeapMode.min)
        for node in graph.nodes():
            minimum_spanning_tree.add_node(node)

            wrapper_node = union_find.Node(node)
            node_to_wrapper_node_map[node] = wrapper_node
            set.make_set(wrapper_node)

        for u, v in graph.edges():
            edge = (node_to_wrapper_node_map[u], node_to_wrapper_node_map[v])
            priority_queue.insert(heap.HeapItem(graph.weight((u, v)), edge))

        while priority_queue.size > 0:
            min_item = priority_queue.extract()
            u_node, v_node = min_item.datum
            if set.find(u_node) != set.find(v_node):
                minimum_spanning_tree.add_undirected_edge(
                    u_node.value, v_node.value, min_item.priority)
                set.union(u_node, v_node)

        return minimum_spanning_tree
Beispiel #21
0
    def test_build_on_two_element_list_as_1_2(self):
        self.heap.build([heap.HeapItem(1), heap.HeapItem(2)])

        self.assertEqual(2, self.heap.size)
        self.assertEqual([heap.HeapItem(2), heap.HeapItem(1)],
                         self.heap.elements)
Beispiel #22
0
    def test_eq_with_priority_as_not_equal(self):
        item = heap.HeapItem(123)
        other = heap.HeapItem(456)

        self.assertFalse(item == other)
        self.assertFalse(other == item)
Beispiel #23
0
    def test_build_on_one_element_list(self):
        self.heap.build([heap.HeapItem(1)])

        self.assertEqual(1, self.heap.size)
        self.assertEqual([heap.HeapItem(1)], self.heap.elements)
Beispiel #24
0
    def test_lt_with_priority_as_equal(self):
        item = heap.HeapItem(123)
        other = heap.HeapItem(123)

        self.assertFalse(item < other)
        self.assertFalse(other < item)
Beispiel #25
0
    def test_insert_on_four_element_list(self):
        self.heap.build([
            heap.HeapItem(2),
            heap.HeapItem(3),
            heap.HeapItem(4),
            heap.HeapItem(5)
        ])

        self.assertEqual(4, self.heap.size)
        self.assertEqual([
            heap.HeapItem(2),
            heap.HeapItem(3),
            heap.HeapItem(4),
            heap.HeapItem(5)
        ], self.heap.elements)

        self.heap.insert(heap.HeapItem(1))

        self.assertEqual(5, self.heap.size)
        self.assertEqual([
            heap.HeapItem(1),
            heap.HeapItem(2),
            heap.HeapItem(4),
            heap.HeapItem(5),
            heap.HeapItem(3)
        ], self.heap.elements)
Beispiel #26
0
    def test_sort_on_seven_element_list_with_duplicates(self):
        list = [
            heap.HeapItem(9),
            heap.HeapItem(5),
            heap.HeapItem(4),
            heap.HeapItem(2),
            heap.HeapItem(5),
            heap.HeapItem(2),
            heap.HeapItem(8)
        ]

        self.heap.sort_in_place(list)

        self.assertEqual([
            heap.HeapItem(9),
            heap.HeapItem(8),
            heap.HeapItem(5),
            heap.HeapItem(5),
            heap.HeapItem(4),
            heap.HeapItem(2),
            heap.HeapItem(2)
        ], list)
        self.assertEqual(7, self.heap.size)
Beispiel #27
0
    def test_constructor_with_priority(self):
        priority = 123
        item = heap.HeapItem(priority)

        self.assertEqual(priority, item.priority)
        self.assertEqual(None, item.datum)
Beispiel #28
0
    def test_lt_with_priority_and_datum_as_not_equal(self):
        item = heap.HeapItem(123, 'datum1')
        other = heap.HeapItem(456, 'datum2')

        self.assertTrue(item < other)
        self.assertFalse(other < item)
Beispiel #29
0
    def test_eq_with_priority_and_datum_as_equal(self):
        item = heap.HeapItem(123, 'datum')
        other = heap.HeapItem(123, 'datum')

        self.assertTrue(item == other)
        self.assertTrue(other == item)
Beispiel #30
0
    def test_change_priority_on_five_element_list_with_sift_up(self):
        self.heap.build([
            heap.HeapItem(3),
            heap.HeapItem(4),
            heap.HeapItem(5),
            heap.HeapItem(6),
            heap.HeapItem(9)
        ])

        self.assertEqual(5, self.heap.size)
        self.assertEqual([
            heap.HeapItem(3),
            heap.HeapItem(4),
            heap.HeapItem(5),
            heap.HeapItem(6),
            heap.HeapItem(9)
        ], self.heap.elements)

        self.heap.change_priority(3, 0)

        self.assertEqual(5, self.heap.size)
        self.assertEqual([
            heap.HeapItem(0),
            heap.HeapItem(3),
            heap.HeapItem(5),
            heap.HeapItem(4),
            heap.HeapItem(9)
        ], self.heap.elements)