Example #1
0
    def setUp(self):
        self.fh = FibonacciHeap()
        #
        # 17    24    23  7  21     3
        #  |    /\                / | \
        # 30  26  46            18 52 41
        #      |                 |     |
        #     35                39    44
        #
        self.elems = {
            v: HeapNode(v)
            for v in (30, 7, 35, 26, 46, 24, 23, 17, 21, 39, 18, 52, 44, 41, 3)
        }
        self.snd_min_elem = sorted(self.elems.values())[1]

        self.elems[41].link(self.elems[44])
        self.elems[18].link(self.elems[39])
        self.elems[3].link(self.elems[41])
        self.elems[3].link(self.elems[52])
        self.elems[3].link(self.elems[18])
        self.fh.add_tree(self.elems[3])
        self.fh.add_tree(self.elems[21])
        self.fh.add_tree(self.elems[7])
        self.fh.add_tree(self.elems[23])
        self.elems[26].link(self.elems[35])
        self.elems[24].link(self.elems[46])
        self.elems[24].link(self.elems[26])
        self.fh.add_tree(self.elems[24])
        self.elems[17].link(self.elems[30])
        self.fh.add_tree(self.elems[17])

        # Remove `3`
        self.fh.extract_min()
        self.exp_num_trees = 3
Example #2
0
 def setUp(self):
     self.fh = FibonacciHeap()
     self.num_elems = 30
     self.elems = [
         HeapNode(random.randint(1, 100)) for i in range(self.num_elems)
     ]
     self.min_elem = min(self.elems)
     for elem in self.elems:
         self.fh.add_tree(elem)
Example #3
0
class OneElemHeapTestCase(unittest.TestCase):
    def setUp(self):
        self.fh = FibonacciHeap()
        self.elem = HeapNode(random.randint(1, 100))
        self.fh.add_tree(self.elem)

    def test_min_elem(self):
        self.assertEqual(self.fh.min_elem, self.elem)

    def test_trees(self):
        self.assertEqual(self.fh.trees, 1)

    def test_extract_min(self):
        self.assertEqual(self.fh.extract_min(), self.elem)
Example #4
0
class Cmplx2HeapTestCase(unittest.TestCase):
    def setUp(self):
        self.fh = FibonacciHeap()
        #
        #            7         18    38
        #        /   |  \      /\     |
        #     24    17   23  21  39  41
        #     / \    |        |
        #   26  46  30       52
        #  / \   |
        # 35 88 72
        #
        self.elems = {
            v: HeapNode(v)
            for v in (41, 38, 39, 52, 21, 18, 23, 30, 17, 72, 46, 88, 35, 26,
                      24, 7)
        }

        self.elems[38].link(self.elems[41])
        self.fh.add_tree(self.elems[38])
        self.elems[21].link(self.elems[52])
        self.elems[18].link(self.elems[39])
        self.elems[18].link(self.elems[21])
        self.fh.add_tree(self.elems[18])
        self.elems[17].link(self.elems[30])
        self.elems[46].link(self.elems[72])
        self.elems[26].link(self.elems[88])
        self.elems[26].link(self.elems[35])
        self.elems[24].link(self.elems[46])
        self.elems[24].link(self.elems[26])
        self.elems[7].link(self.elems[23])
        self.elems[7].link(self.elems[17])
        self.elems[7].link(self.elems[24])
        self.fh.add_tree(self.elems[7])

        self.elems[29] = self.fh.dec_key(self.elems[46], 29)
        del self.elems[46]

        self.elems[15] = self.fh.dec_key(self.elems[29], 15)
        del self.elems[29]

        self.elems[35].parent.mark()
        self.elems[35].parent.parent.mark()
        self.elems[5] = self.fh.dec_key(self.elems[35], 5)
        self.exp_num_trees = 7

        self.min_elem = min(self.elems.values())

    def test_min_elem(self):
        self.assertEqual(self.fh.min_elem, self.min_elem)

    def test_trees(self):
        self.assertEqual(self.fh.trees, self.exp_num_trees)
Example #5
0
    def dijkstra(self, source):
        """
        Computes Dijkstra's algorithm (shortest path from 
        a source vertex to all other verticies). 
        
        Assumption(s):
            - "source" is in the graph.
            - The graph has no negative edge-weights.
            - The graph has no negative cycles.

        :param source: The vertex to perform Dijkstra's on.
        :return Two dictionaries:
            -A dictionary containing the cost to traverse from "source" to each
            reachable vertex in the graph.
            -A dictionary encoding the shortest path from "source" to each
            reachable vertex in the graph.
        """

        V = self.get_vertices()
        dist, prev = {}, {}

        assert source in V

        pq = FibonacciHeap()
        for v in V:
            dist[v] = INFINITY if v != source else 0
            prev[v] = None
            pq.push(v, dist[v])

        while not pq.empty():
            u = pq.pop()

            neighbors = self.get_neighbors(u)
            for neighbor in neighbors:
                alt = dist[u] + self.get_edge_value(u, neighbor)
                if alt >= dist[neighbor]:
                    continue

                dist[neighbor] = alt
                prev[neighbor] = u

                if neighbor not in pq:
                    pq.push(neighbor, alt)
                else:
                    pq.decrease_key(neighbor, alt)

        return dist, prev
Example #6
0
class ManyElemHeapTestCase(unittest.TestCase):
    def setUp(self):
        self.fh = FibonacciHeap()
        self.num_elems = 30
        self.elems = [
            HeapNode(random.randint(1, 100)) for i in range(self.num_elems)
        ]
        self.min_elem = min(self.elems)
        for elem in self.elems:
            self.fh.add_tree(elem)

    def test_min_elem(self):
        self.assertEqual(self.fh.min_elem, self.min_elem)

    def test_trees(self):
        self.assertEqual(self.fh.trees, self.num_elems)

    def test_extract_min(self):
        self.assertEqual(self.fh.extract_min(), self.min_elem)
Example #7
0
class EmptyHeapTestCase(unittest.TestCase):
    def setUp(self):
        self.fh = FibonacciHeap()

    def test_min_elem(self):
        self.assertEqual(self.fh.min_elem, None)

    def test_trees(self):
        self.assertEqual(self.fh.trees, 0)

    def test_extract_min(self):
        self.assertEqual(self.fh.extract_min(), None)
Example #8
0
    def mst(self):
        """
        Computes the minimum spanning tree of the graph using
        Prim's algorithm.

        :return: The minimum spanning tree (in a list of connecting edges).
        """

        V = self.get_vertices()
        heap = FibonacciHeap()
        cost, prev = {}, {}

        for u in V:
            cost[u] = INFINITY
            prev[u] = None

        v = random.choice(V)
        cost[v] = 0
        for u in V:
            heap.push(u, cost[u])

        while not heap.empty():
            u = heap.pop()
            neighbors = self.get_neighbors(u)
            for v in neighbors:
                edge_weight = self.get_edge_value(u, v)
                if v in heap and cost[v] > edge_weight:
                    cost[v] = edge_weight
                    prev[v] = u
                    heap.decrease_key(v, cost[v])

        mst = set()
        for v in V:
            if prev[v] is None:
                continue

            edge = (prev[v], v) if prev[v] < v else (v, prev[v])
            mst.add(edge)

        return mst
Example #9
0
def dijkstra(vertice_list, src, num_ver):
    parent = []
    #marca todos os vertices como nao visitados
    for i in range(num_ver):
        parent.append(-1)
    #vertice inicial tem distancia 0.  Na 1 iteracao todos os demais estao setados com 'infinidade'
    vertice_list[src].dist = 0

    from fibheap import FibonacciHeap
    f = FibonacciHeap()
    f.insert(vertice_list[src].dist, src)
    #print("Nodes:",f.total_nodes)
    #pelo numero de vertices, escolha o vertice de menor distancia atualmente no grafo.
    #Na primeira iteracao sera o source.
    i = 0
    while (f.total_nodes != 0):
        #while(i<10):
        i += 1
        #print(i)
        v_min_node = f.extract_min()  # 1.1
        #print('key:',v_min_node.key)
        #print("Nodes:",f.total_nodes)
        v_min = vertice_list[v_min_node.value]

        if (v_min == None):
            continue
        v_min.visited = 1  #marque vertice minimo como ja visitado. Desse modo o 1.2 sera feito, pois nao sera mais contado
        #para cada vertice adjacente ao vertice minimo
        for key in v_min.adjs:  # 1.3
            adj_ver = vertice_list[
                v_min.adjs[key].id]  #pega o vertice adjacente
            #Se a distancia atual do vertice minimo, mais o seu peso, for menor que a distancia do vert adjacente
            if (adj_ver.visited == 0
                    and v_min.dist + v_min.weights[key] < adj_ver.dist):
                adj_ver.dist = v_min.dist + v_min.weights[
                    key]  #a distancia do vertice adjacente tera esse novo valor
                parent[
                    adj_ver.
                    id] = v_min.id  # a pos que era do vertice adjacente, sera do menor v agora
                f.insert(adj_ver.dist, adj_ver.id)
Example #10
0
 def setUp(self):
     self.fh = FibonacciHeap()
     self.elem = HeapNode(random.randint(1, 100))
     self.fh.add_tree(self.elem)
Example #11
0
 def setUp(self):
     self.fh = FibonacciHeap()