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())
class TestDeleteMin(unittest.TestCase): def setUp(self): self.h = Heap() self.h.insert(5, 'Five') def test_one_and_empty(self): self.assertEqual(self.h.delete_min(), 'Five') self.assertIsNone(self.h.delete_min()) def test_left(self): self.h.insert(8, 'Eight') self.assertEqual(self.h.delete_min(), 'Five') self.assertEqual(self.h.heap[0].val, 'Eight') def test_right(self): self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.assertEqual(self.h.delete_min(), 'Five') self.assertEqual(self.h.heap[0].val, 'Eight') self.assertEqual(self.h.heap[1].val, 'Ten') def test_dupe(self): self.h.insert(5, 'Five') self.assertEqual(self.h.delete_min(), 'Five') self.assertEqual(self.h.heap[0].val, 'Five') def test_new_min(self): self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(3, 'Three') self.assertEqual(self.h.delete_min(), 'Three') self.assertEqual(self.h.heap[0].val, 'Five') def test_multiple(self): self.h.insert(3, 'Three') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(13, 'Thirteen') self.h.insert(11, 'Eleven') self.h.insert(12, 'Twelve') self.h.insert(4, 'Four') self.assertEqual(self.h.delete_min(), 'Three') self.assertEqual(self.h.delete_min(), 'Four') self.assertEqual(self.h.delete_min(), 'Five') self.assertEqual(self.h.delete_min(), 'Eight') self.assertEqual(self.h.delete_min(), 'Ten')
class TestUpheap(unittest.TestCase): def setUp(self): self.h = Heap() self.h.insert(5, 'Five') def test_once_left(self): self.h.heap.append(Node(3, 'Three')) self.h._upheap(1) self.assertEqual(self.h.heap[0].val, 'Three') self.assertEqual(self.h.heap[1].val, 'Five') def test_once_right(self): self.h.insert(8, 'Eight') self.h.heap.append(Node(3, 'Three')) self.h._upheap(2) self.assertEqual(self.h.heap[0].val, 'Three') self.assertEqual(self.h.heap[2].val, 'Five') def test_many(self): self.h.insert(3, 'Three') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(13, 'Thirteen') self.h.insert(11, 'Eleven') self.h.insert(12, 'Twelve') self.h.insert(4, 'Four') self.h.heap.append(Node(2, 'Two')) self.h._upheap(len(self.h.heap) - 1) self.assertEqual(self.h.heap[0].val, 'Two')
class TestInsert(unittest.TestCase): def setUp(self): self.h = Heap() def test_empty(self): self.h.insert(5, 'Five') self.assertEqual(self.h.heap[0].val, 'Five') def test_left(self): self.h.insert(5, 'Five') self.h.insert(8, 'Eight') self.assertEqual(self.h.heap[1].val, 'Eight') def test_right(self): self.h.insert(5, 'Five') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.assertEqual(self.h.heap[2].val, 'Ten') def test_new_min(self): self.h.insert(5, 'Five') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(3, 'Three') self.assertEqual(self.h.heap[0].val, 'Three') self.assertEqual(self.h.heap[1].val, 'Five') self.assertEqual(self.h.heap[2].val, 'Ten') self.assertEqual(self.h.heap[3].val, 'Eight') def test_dupe(self): self.h.insert(5, 'Five') self.h.insert(8, 'Eight') self.h.insert(5, 'Five') self.assertEqual(self.h.heap[0].val, 'Five') self.assertEqual(self.h.heap[1].val, 'Eight') self.assertEqual(self.h.heap[2].val, 'Five') def test_middle(self): self.h.insert(3, 'Three') self.h.insert(5, 'Five') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(13, 'Thirteen') self.h.insert(11, 'Eleven') self.h.insert(12, 'Twelve') self.h.insert(4, 'Four') self.assertEqual(self.h.heap[0].val, 'Three') self.assertEqual(self.h.heap[1].val, 'Four') self.assertEqual(self.h.heap[3].val, 'Five')
class TestDownheap(unittest.TestCase): def setUp(self): self.h = Heap() self.h.insert(5, 'Five') def test_once_left(self): self.h.heap.append(Node(2, 'Two')) self.h.heap.append(Node(3, 'Three')) self.h._downheap(0) self.assertEqual(self.h.heap[0].val, 'Two') self.assertEqual(self.h.heap[1].val, 'Five') def test_once_right(self): self.h.heap.append(Node(3, 'Three')) self.h.heap.append(Node(2, 'Two')) self.h._downheap(0) self.assertEqual(self.h.heap[0].val, 'Two') self.assertEqual(self.h.heap[2].val, 'Five') def test_many_left(self): self.h.insert(3, 'Three') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(13, 'Thirteen') self.h.insert(11, 'Eleven') self.h.insert(12, 'Twelve') self.h.insert(4, 'Four') self.h.insert(2, 'Two') self.h.heap.pop() self.h.heap[0] = Node(5, 'Five') self.h._downheap(0) self.assertEqual(self.h.heap[0].val, 'Three') self.assertEqual(self.h.heap[1].val, 'Four') self.assertEqual(self.h.heap[3].val, 'Five') with self.assertRaises(IndexError): self.h.heap[8] def test_many_right(self): self.h.insert(3, 'Three') self.h.insert(8, 'Eight') self.h.insert(10, 'Ten') self.h.insert(13, 'Thirteen') self.h.insert(11, 'Eleven') self.h.insert(12, 'Twelve') self.h.insert(4, 'Four') self.h.insert(2, 'Two') self.h.insert(15, 'Fifteen') self.h.insert(9, 'Nine') self.h.insert(14, 'Fourteen') self.h.insert(1, 'One') self.h.heap.pop() self.h.heap[0] = Node(11, 'Eleven') self.h._downheap(0) self.assertEqual(self.h.heap[0].val, 'Two') self.assertEqual(self.h.heap[2].val, 'Eight') self.assertEqual(self.h.heap[5].val, 'Eleven') with self.assertRaises(IndexError): self.h.heap[12]