def prim(G, root=None): """ Find the minimim spanning tree of a graph using Prim's algorithm. If root is given, use it as the starting node. """ nodes = Heap([(float("inf"), n) for n in G.nodes]) parent = {n: None for n in G.nodes} if root: nodes[root] = 0 mst = set() while nodes: node = nodes.pop()[0] if parent[node] is not None: mst.add((parent[node], node)) for neigh, weight in G[node].items(): if neigh in nodes and weight < nodes[neigh]: nodes[neigh] = weight parent[neigh] = node return mst
def dijkstra_heap(graph,source,stress = False): n_nodes = len(graph) Q = [True] * n_nodes dist = [MAX_INT] * n_nodes #distance from source to v prev = [None] * n_nodes #previous node in optimal path dist[source] = 0 S = Heap() for node,distance in enumerate(dist): S.insert((distance,node)) while S.size != 0: #find vertex with minimum distance dist_u , u = S.pop() #instead of finding the minimum we just grab it. O(logn) vs O(n) Q[u] = False weights = graph[u] for v,edge in enumerate(weights): # can I find a way to relate this to the decrease priority? # yes. we need to iterate the heap itself and not the weight array if edge != MAX_INT and Q[v]: #v is in Q and is neighbor #we need some way of relating this to the heap alt = dist_u + edge #alternative path if alt < dist[v]: #alternative path is better dist[v] = alt prev[v] = u S.decrease_priority(v,alt) if stress: #progress tracker - to be removed print(str(S.size)+'\r',end = '') return (dist,prev)
class TestSequenceFunctions(unittest.TestCase): def setUp(self): self.heap = Heap([(int(x), str(x)) for x in random.sample(xrange(10, 90), 10)]) def test_Node_init(self): node = Node(name="name", key="key") node.pos = 0 self.assertTrue( all((node.name == "name", node.key == "key", node.pos == 0))) def test_Node_cmp(self): node1 = Node(20, "node1") node2 = Node(1, "node2") self.assertTrue(node2 < node1) def test_Heap_init(self): node1 = (20, "node1") node2 = (1, "node2") self.heap = Heap([node1, node2], named=True) self.assertTrue( self.heap["node1"].pos == 1 and self.heap["node2"].pos == 0) def test_Heap_bubble_up(self): node = Node(1, "1") node.pos = len(self.heap.node_array) self.heap.node_array.append(node) self.heap.node_lookup[node.name] = node.pos self.assertFalse(self.heap.is_heap_property_satisfied()) self.heap.bubble_up() self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_bubble_down(self): node = Node(100, "100") node.pos = 0 self.heap.node_array[0] = node self.assertFalse(self.heap.is_heap_property_satisfied()) self.heap.bubble_down() self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_getitem(self): node = random.choice(self.heap.node_array) self.assertTrue(self.heap[node.name] == node) def test_Heap_insert(self): node = Node(1000, "1000") self.assertTrue(self.heap.is_heap_property_satisfied()) self.heap.insert(node) self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_delete_first(self): node = random.choice(self.heap.node_array) node = self.heap.node_array[0] self.assertTrue(self.heap.is_heap_property_satisfied()) self.heap.delete(node) self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_delete_last(self): node = self.heap.node_array[-1] self.assertTrue(self.heap.is_heap_property_satisfied()) self.heap.delete(node) self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_delete_random(self): node = random.choice(self.heap.node_array) self.assertTrue(self.heap.is_heap_property_satisfied()) self.heap.delete(node) self.assertTrue(self.heap.is_heap_property_satisfied()) def test_Heap_pop(self): min_node = self.heap.node_array[0] popped_node = self.heap.pop() self.assertTrue(self.heap.is_heap_property_satisfied()) self.assertTrue(popped_node == min_node) def test_Heap_update_key(self): node = random.choice(self.heap.node_array) node_name = node.name new_key = random.choice(xrange(0, 1000)) self.heap.update_key(node_name, new_key) self.assertTrue(self.heap.is_heap_property_satisfied())