def kruskal_method(graph):
    """
    This method is not the same code as in the textbook, but the idea is the same.
    """
    clusters = {v: [v, 1] for v in graph.vertices()}
    heap = Heap(((e.element, e) for e in graph.edges()))
    shortest_edges = set()

    while (len(shortest_edges) < graph.vertex_count() - 1) and heap:
        _, edge = heap.pop_min()
        v1, v2 = edge.endpoints()
        v1_head, v2_head = v1, v2
        while v1_head != clusters[v1_head][0]:
            v1_head = clusters[v1_head][0]
        while v2_head != clusters[v2_head][0]:
            v2_head = clusters[v2_head][0]
        clusters[v1][
            0] = v1_head  # This is not necessary to run this method, but it may speed up the process
        clusters[v2][
            0] = v2_head  # This is not necessary to run this method, but it may speed up the process

        if v1_head != v2_head:
            shortest_edges.add(edge)
            c_big, c_small = (
                clusters[v1_head], clusters[v2_head]
            ) if clusters[v1_head][1] > clusters[v2_head][1] else (
                clusters[v2_head], clusters[v1_head])
            c_big[1] += c_small[1]
            c_small[0] = c_big[0]
    return shortest_edges
    def _build_tree(self, freq_table):
        heap = Heap()
        for char, freq in freq_table.items():
            heap[freq] = HuffmanTree(char, freq)

        while len(heap) > 1:
            t1 = heap.pop_min()
            t2 = heap.pop_min()
            t = t2 + t1
            heap[t.key()] = t
        tree = heap.pop_min()
        self.tree = tree
def dijkstra_method_simplify(graph, start):
    """ This function cannot report unreachable vertices at the beginning. One
        should compare the distances's key with graph's vertices to show those
        unreachable vertices.
    """
    heap = Heap([(0, start)])
    distances = {}
    while heap and len(distances) < graph.vertex_count():
        distance, vertex = heap.pop_min()
        if vertex not in distances:
            distances[vertex] = distance
            for v_oppo, edge in graph.incident_edges(vertex):
                if v_oppo not in distances:
                    heap[edge.element + distances[vertex]] = v_oppo
    return distances
def dijkstra_method(graph, start):
    """ This function can detect if start vertex can reach to any vertices in the
        rest of the graph. If any vertex cannot be reached, then
        distances[vertex cannot be reached] = inf.
    """
    heap = Heap([(0, start)])
    found = set()
    distances = {v: inf for v in graph.vertices()}
    while heap and len(found) < graph.vertex_count():
        distance, vertex = heap.pop_min()
        if vertex not in found:
            found.add(vertex)
            distances[vertex] = distance
            for v_oppo, edge in graph.incident_edges(vertex):
                if v_oppo not in found:
                    heap[edge.element + distances[vertex]] = v_oppo
    return distances
def dijkstra_method_with_path(graph, start):
    """ This function can detect if start vertex can reach to any vertices in the
        rest of the graph. If any vertex cannot be reached, then
        distances[vertex cannot be reached] = inf.
    """
    heap = Heap([(0, [start])])
    found = set()
    distances = {v: inf for v in graph.vertices()}
    while heap and len(found) < graph.vertex_count():
        distance, path = heap.pop_min()
        vertex = path[-1]
        if vertex not in found:
            found.add(vertex)
            distances[vertex] = [distance, path.copy()]
            for v_oppo, edge in graph.incident_edges(vertex):
                if v_oppo not in found:
                    new_path = path.copy()
                    new_path.append(v_oppo)
                    heap[edge.element + distances[vertex][0]] = new_path
    return distances
def prim_jarnik_method(graph):
    """
    This method is not exactly the same code as in the textbook, but the idea is the same.
    """
    vertices = {v for v in graph.vertices()}
    heap = Heap(((e.element, e)
                 for _, e in graph.incident_edges(vertices.pop(), False)))
    shortest_edges = set()

    while vertices and heap:
        _, edge = heap.pop_min()
        v1, v2 = edge.endpoints()
        if (v1 not in vertices) ^ (v2 not in vertices):
            shortest_edges.add(edge)
            vertex = v1 if v1 in vertices else v2
            vertices.remove(vertex)
            for v_oppo, edge in graph.incident_edges(vertex, False):
                if v_oppo in vertices:
                    heap[edge.element] = edge
    return shortest_edges
Example #7
0
 def restore(self):
     heap = Heap()
     for word, indices in self._word_in_trie(self.root):
         for index in indices:
             heap[index] = word
     return ''.join(heap.pop_min() for _ in range(len(heap)))