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
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
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
def setUp(self): self.heap = heap.BinHeap(heap.HeapMode.max)