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
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)))