def test_key_function(self): fruits = ['Watermelon', 'blueberry', 'lime', 'Lemon', 'pear', 'loquat'] fruits_heap = MinHeap(fruits, key=str.lower) self.assertEqual(fruits_heap.peek(), 'blueberry') fruits_heap.push('Apple') fruits_heap.push('jujube') self.assertEqual(fruits_heap.pop(), 'Apple') self.assertEqual(fruits_heap.pop(), 'blueberry') self.assertEqual(fruits_heap.pop(), 'jujube') self.assertEqual(fruits_heap.pop(), 'Lemon')
def test_pop(self): item_0 = {"id":1, "price":1.0} item_1 = {"id":2, "price":2.0} item_2 = {"id":3, "price":.0} heap = MinHeap() heap.push(item_0) heap.push(item_1) heap.push(item_2) self.assertEqual(heap.pop(), item_2) self.assertEqual(heap.pop(), item_0) self.assertEqual(heap.pop(), item_1)
class TestMinHeapWithTuples(unittest.TestCase): def setUp(self): self.h = MinHeap( elements=[(4, 101), (12, 9), (13, 5), (2, 1), (6, 1001), (5, 45), (10, 121)]) def test_correct_order(self): self.assertEqual( self.h.h, [(2, 1), (4, 101), (5, 45), (12, 9), (6, 1001), (13, 5), (10, 121)], ) def test_insert_99_1(self): self.assertEqual(self.h.insert((1, 99)), 0) self.assertEqual( self.h.h, [ (1, 99), (2, 1), (5, 45), (4, 101), (6, 1001), (13, 5), (10, 121), (12, 9), ], ) def test_update_min(self): self.assertTrue((13, 5) in self.h) self.assertTrue((11, 5) not in self.h) self.h.update_min(11, 5) self.assertTrue((11, 5) in self.h) self.assertTrue((13, 5) not in self.h) self.assertEqual( self.h.h, [(2, 1), (4, 101), (5, 45), (12, 9), (6, 1001), (11, 5), (10, 121)], ) def test_pop(self): self.assertEqual(len(self.h.h), 7) self.assertEqual(self.h.pop(), (2, 1)) self.assertEqual(self.h.pop(), (4, 101)) self.assertEqual(self.h.pop(), (5, 45)) self.assertEqual(self.h.pop(), (6, 1001)) self.assertEqual(len(self.h.h), 3) self.assertEqual(self.h.h, [(10, 121), (12, 9), (13, 5)])
def test_pop_from_heap(self): numbers = [11, 322, 3, 199, 29, 7, 1, 18, 76, 4, 2, 47, 123] h = MinHeap(numbers) self.assertEqual(h.pop(), 1) self.assertEqual(len(h), len(numbers)-1) self.assertEqual(h.pop(), 2) self.assertEqual(h.pop(), 3) self.assertEqual(h.pop(), 4) self.assertEqual(len(h), len(numbers)-4) self.assertEqual(h.pop(), 7) self.assertEqual(h.pop(), 11) self.assertEqual(len(h), len(numbers)-6) i = MinHeap(BIG_NUMBERS) self.assertEqual(i.pop(), 46)
def dsp(graph: list, s, t) -> int: """ Find shortest path from two vertices via Dijkstra's shortest-path algorithm. Args: s: source vertex t: the target vertex Returns: Shortest path from `s` to `t` vertices """ if s == t: return 0 # Vertices seen so far visited = [] heap = MinHeap([(10000000, v) for v in range(1, len(graph))]) heap.update_min(0, s) while not heap.is_empty(): dist, u = heap.pop() visited.append(u) if u == t: return dist for v, d in graph[u]: if v not in visited: heap.update_min(dist + d, v)
def test_push_onto_heap(self): numbers = [11, 322, 3, 199, 29, 7, 1, 18, 76, 4, 2, 47, 123] i = MinHeap(BIG_NUMBERS) i.push(17) self.assertEqual(i.peek(), 17) i.push(24) self.assertEqual(i.pop(), 17) self.assertEqual(i.pop(), 24) self.assertEqual(i.pop(), 46) h = MinHeap(numbers) h.push(6) self.assertEqual(len(h), len(numbers)+1) self.assertEqual(h.pop(), 1) self.assertEqual(h.pop(), 2) self.assertEqual(h.pop(), 3) self.assertEqual(h.pop(), 4) self.assertEqual(h.pop(), 6)
class TestMinHeapSort(unittest.TestCase): def setUp(self): self.h = MinHeap( values=[(4, 101), (12, 9), (13, 5), (2, 1), (6, 1001), (5, 45), (10, 121)]) def test_correct_order(self): self.assertEqual( self.h.h, [(2, 1), (4, 101), (5, 45), (12, 9), (6, 1001), (13, 5), (10, 121)], ) def test_insert_99_1(self): self.assertEqual(self.h.insert((1, 99)), 0) self.assertEqual( self.h.h, [ (1, 99), (2, 1), (5, 45), (4, 101), (6, 1001), (13, 5), (10, 121), (12, 9), ], ) def test_pop(self): self.assertEqual(len(self.h.h), 7) self.assertEqual(self.h.pop(), (2, 1)) self.assertEqual(self.h.pop(), (4, 101)) self.assertEqual(self.h.pop(), (5, 45)) self.assertEqual(self.h.pop(), (6, 1001)) self.assertEqual(len(self.h.h), 3) self.assertEqual(self.h.h, [(10, 121), (12, 9), (13, 5)])
def test_faster_than_sorting(self): with Timer() as sort_timer: sorted(MANY_BIG_NUMBERS) heap = MinHeap(MANY_BIG_NUMBERS) with Timer() as min_heap_timer: heap.push(150) heap.push(950) heap.push(400) heap.push(760) heap.push(280) heap.push(870) heap.push(330) heap.push(1000) heap.push(50) heap.push(500) items = [heap.pop() for _ in range(10)] self.assertEqual(len(items), 10) self.assertLess(min_heap_timer.elapsed, sort_timer.elapsed)
def a_star_search(init_state , target_state) : heap = MinHeap() heap.push(init_state) print '++++++++++++++' cnt = 0 while True : if heap.empty() : return None cnt += 1 cur_state = heap.pop() if cur_state.is_same2other_state(target_state) : return cur_state states_lst = cur_state.expand_states() for state in states_lst : state.set_cost4a_star(target_state) if not heap.has_same(state , Puzzle8State.is_2puzzle_same) : heap.push(state) if cnt%1000 == 0 : print "state {0} has been searched , currently heap has {1} states .".format(cnt , heap.size())
def split(self, x, y): """Find (n_class-1) best thresholds for a feature x and corresponding labels y. Args: x: a feature. y: the labels. Returns: a list of the best thresholds(x-value). """ heap = MinHeap(self.n_class) sort_index = sorted(range(len(x)), key=lambda i: x[i]) x_sort = x[sort_index] y_sort = y[sort_index] thres_i, ig = self.split_by_entropy(x_sort, y_sort, sort=False) heap.push((tuple(range(len(y))), thres_i), -ig) while heap.size < self.n_class and heap.minimum() < 0: (piece, thres), ig = heap.pop() piece1, piece2 = list(piece[:thres]), list(piece[thres:]) thres_i1, ig1 = self.split_by_entropy(x_sort[piece1], y_sort[piece1], sort=False) thres_i2, ig2 = self.split_by_entropy(x_sort[piece2], y_sort[piece2], sort=False) heap.push((piece1, thres_i1), -ig1) heap.push((piece2, thres_i2), -ig2) return x_sort[sorted([item[0][0][-1] for item in heap.items()])[:-1]]
class MinHeapTest(unittest.TestCase): @classmethod def setUpClass(self): self.H = MinHeap() self.data = [('A',7),('B',3),('C',4),('D',1),('E',6),('F',5),('G',2)] @classmethod def tearDownClass(self): self.H = None def check_assertions(self,heap_val,data_val,size_val): self.assertEqual(self.H.heap,heap_val,'Non-Empty Heap') self.assertEqual(self.H.data,data_val,'Non-Empty Data') self.assertEqual(self.H.size,size_val,'Non-Zero Size') def test_empty_heap_1_func(self): self.H.emptyHeap() self.check_assertions([],{},0) def test_empty_heap_2_pop(self): self.assertRaises(Exception,self.H.pop) def test_empty_heap_3_find(self): self.assertRaises(Exception,self.H.find,'A') def test_empty_heap_4_peek(self): self.assertRaises(Exception,self.H.peek) def test_empty_heap_5_heapify(self): self.H.heapify() self.check_assertions([],{},0) def test_empty_heap_6_update(self): self.assertRaises(Exception,self.H.update,'A',3) def test_single_entry_heap_1_push(self): self.H.emptyHeap() self.H.push('A',3) self.check_assertions([('A',[3])],{'A':[[3],0]},1) def test_single_entry_heap_2_find(self): self.assertEqual(self.H.find('A'),3) self.assertRaises(Exception,self.H.find,'B') def test_single_entry_heap_3_peek(self): self.assertEqual(self.H.peek(),('A',3)) def test_single_entry_heap_4_heapify(self): self.H.heapify() self.check_assertions([('A',[3])],{'A':[[3],0]},1) def test_single_entry_heap_5_update(self): self.H.update('A',7) self.check_assertions([('A',[7])],{'A':[[7],0]},1) def test_single_entry_heap_6_pop(self): self.assertEqual(self.H.pop(),('A',7)) self.check_assertions([],{},0) def check_heap_order_property(self): N = self.H.size for k in range(N): x,y = self.H.heap[k] self.assertEqual(self.H.data[x],[y,k]) childOne,childTwo,parent = 2*k+1,2*k+2,(k-1)//2 if parent >= 0: p = self.H.heap[parent] self.assertGreater(y,p[1]) self.assertEqual(self.H.data[p[0]],[p[1],parent]) if childOne < N: c = self.H.heap[childOne] self.assertLess(y,c[1]) self.assertEqual(self.H.data[c[0]],[c[1],childOne]) if childTwo < N: c = self.H.heap[childTwo] self.assertLess(y,c[1]) self.assertEqual(self.H.data[c[0]],[c[1],childTwo]) def test_multiple_entry_heap_1_push(self): self.H.emptyHeap() for k,v in self.data: self.H.push(k,v) self.check_heap_order_property() def test_multiple_entry_heap_2_peek(self): self.assertEqual(self.H.peek(),('D',1)) def test_multiple_entry_heap_3_find(self): for k,v in self.data: self.assertEqual(self.H.find(k),v) def test_multiple_entry_heap_4_heapify(self): values = self.H.data.values() self.H.heapify() self.assertEqual(values,self.H.data.values()) def test_multiple_entry_heap_5_update(self): self.H.update('G',8) self.check_heap_order_property() self.H.update('E',0) self.check_heap_order_property() self.H.update('E',9) self.check_heap_order_property() self.H.update('F',2) self.check_heap_order_property() self.H.update('G',2) self.H.update('E',6) self.H.update('F',5) self.check_heap_order_property() def test_multiple_entry_heap_6_pop(self): heap_sorted = [] while not self.H.isEmpty(): heap_sorted.append(self.H.pop()) self.assertEqual(heap_sorted,sorted(self.data,key=lambda (x,y): y)) self.check_assertions([],{},0)
class TestMinHeap(unittest.TestCase): def setUp(self): self.heap = MinHeap() def test_clear(self): """Calling clear for a heap sets its array to an empty list and size to zero. (0p)""" self.heap.array = [(1, 1)] self.heap.size = 1 self.heap.clear() self.assertListEqual( [], self.heap.array, "heap.clear() should set heap.array to an empty list.") self.assertEqual(0, self.heap.size, "heap.clear() should set heap.size to 0.") def test_empty_heap_size(self): """The size of an empty heap is zero. (0p)""" self.assertEqual(0, self.heap.size, "The size of an empty heap should be zero.") def test_empty_heap_is__empty(self): """is_empty returns True for an empty heap. (0p)""" self.assertTrue( self.heap.is_empty(), "Calling is_empty should return True for an empty heap instance.") def test_higher_priority_high_low(self): """_higher_priority returns True when comparing an element with a higher priority to an element with a lower priority. (1p)""" self.heap.array = [(1, 'important'), (2, 'not important')] self.assertTrue( self.heap._higher_priority(0, 1), "_higher_priority priority should return True when comparing {0} to {1}" .format(self.heap.array[0], self.heap.array[1])) def test_higher_priority_low_high(self): """_higher_priority returns False when comparing an element with a lower priority to an element with a higher priority. (1p)""" self.heap.array = [(1, 'important'), (2, 'not important')] self.assertFalse( self.heap._higher_priority(1, 0), "_higher_priority priority should return False when comparing {0} to {1}" .format(self.heap.array[1], self.heap.array[0])) def test_size_after_insert(self): """Inserting values into the heap increments the size counter. (1p)""" inserted_tasks = generate_tasks_with_priorities() for pair in inserted_tasks: self.heap.insert(pair) inserted_count = len(inserted_tasks) current_size = self.heap.size self.assertEqual( inserted_count, current_size, "After inserting {0} pairs, the size of the heap should be {0}, not {1}" .format(inserted_count, current_size) + '\n' + heap_array_to_string(self.heap.array)) def test_empty_heap_top(self): """Calling top on an empty heap returns None. (1p)""" self.assertIsNone( self.heap.top(), "Calling heap.top() should return None for an empty heap instance." ) def test_empty_heap_pop(self): """Calling pop on an empty heap raises an exception. (1p)""" msg = "Calling heap.pop() should raise a RuntimeError for an empty heap instance." with self.assertRaises(RuntimeError, msg=msg): self.heap.pop() def test_top_after_insert(self): """Calling top always returns the object with the smallest priority value. (1p)""" inserted_tasks = generate_tasks_with_priorities() shuffled = list(inserted_tasks) random.shuffle(shuffled) for pair in shuffled: self.heap.insert(pair) expected_value = inserted_tasks[0][1] returned_value = self.heap.top() self.assertIs( returned_value, expected_value, "Calling top should have returned {0}, not {1}.".format( expected_value, returned_value) + '\n' + heap_array_to_string(self.heap.array)) def test_pop_after_insert(self): """Calling pop always returns the object with the smallest priority value and removes it from the heap. (1p)""" inserted_tasks = generate_tasks_with_priorities() shuffled = list(inserted_tasks) random.shuffle(shuffled) for pair in shuffled: self.heap.insert(pair) for i, pair in enumerate(inserted_tasks): assertmsg = "Before calling pop, the heap array in your solution looked like this:" heap_array_before_pop = self.heap.array[:] popped_value = self.heap.pop() expected_value = pair[1] self.assertIs( popped_value, expected_value, "Calling pop should have returned {0}, not {1}.".format( expected_value, popped_value) + '\n' + heap_array_to_string(heap_array_before_pop, assertmsg)) removed_count = i + 1 self.assertEqual( len(self.heap.array), len(inserted_tasks) - removed_count, "Calling pop should remove the object with the smallest priority value from the heap array." + '\n' + heap_array_to_string(heap_array_before_pop, assertmsg))
def test_pop_empty(self): h = MinHeap() self.assertIsNone(h.pop()) self.assertEqual(h.h, [])