def test_is_min_heap(self): root = Node(0) root.left = Node(1) root.right = Node(2) root.left.left = Node(3) self.assertTrue(isinstance(heap.MinHeap(root), heap.MinHeap)) root.left.value = 4 self.assertRaises(Exception, heap.MinHeap, root) # not ordered root.left.value = 1 root.right.left = Node(5) self.assertRaises(Exception, heap.MinHeap, root) # not complete root.left.right = Node(6) self.assertTrue(isinstance(heap.MinHeap(root), heap.MinHeap))
def find_Kth_largest_v5(nums, k): heapx = theHeap.MinHeap('MAX') max_heap = heapx.build_heap(nums) for _ in range(k - 1): heapx.heappop(max_heap) return max_heap[0]
def dijkstra(G, s): initialize_single_source(G, s) S = set() Q = heap.MinHeap(G.vertices()) while len(Q): u = Q.extract_min() S.add(u) for v in G.neighbors(u): relax(u, v, G.weight(u, v)) # decrease_key!!
def _init_top_n(self, n): """Initialize the framework required to track the top-N items. Extracted to a separate method to ease subclassing. :param n: The number of top items to track :return: None """ self.n = n self.heap = heap.MinHeap() self.heap_full = False self.top_n = {}
def test_insert(self): root = Node(1) root.left = Node(2) root.right = Node(3) root.left.left = Node(4) min_heap = heap.MinHeap(root) min_heap.insert(0) self.assertTrue(min_heap.is_min_heap) self.assertEqual(min_heap.root.value, 0) self.assertEqual(min_heap.root.left, 1) self.assertEqual(min_heap.root.right, 3) self.assertEqual(min_heap.root.left.left, 4) self.assertEqual(min_heap.root.left.left, 2)
def test_extract_min(self): root = Node(1) root.left = Node(2) root.right = Node(3) root.left.left = Node(4) root.left.right = Node(5) min_heap = heap.MinHeap(root) min = min_heap.extract_min() self.assertEqual(min, 1) self.assertEqual(min_heap.is_min_heap) self.assertEqual(min_heap.root.value, 2) self.assertEqual(min_heap.root.left.value, 4) self.assertEqual(min_heap.root.right.value, 3) self.assertEqual(min_heap.root.left.left.value, 5)
def kClosest_v2(points, k): '''# KLOGN''' heapqq = theHeap.MinHeap() heap, res = [], [] for point in points: x, y = point dist = (x**2) + (y**2) heapqq.heappush(heap, [dist, point]) for _ in range(k): _, point = heapqq.heappop(heap) res.append(point) return res
def find_shortest_path(self): """Finds a solution to the traveling salesman problem.""" source = random.randint(0, self.node_graph.number_of_nodes() - 1) open_list = heap.MinHeap() closed_list = [] source_node = aStarNode.AStarNode( source, self.node_graph.nodes[source].coordinates, -1, 0, 0) open_list.insert(source_node) path_found = False while not open_list.empty() and not path_found: current_node = open_list.extract_min() closed_list.append(current_node) if self._goal_state(closed_list): path_found = True continue adjacent = self._get_adjacent_nodes(current_node, source, closed_list) for _, node in enumerate(adjacent): node_position = open_list.get_index(node) node_closed = False for _, closed_node in enumerate(closed_list): if node.nodeLabel == closed_node.nodeLabel: node_closed = True break if not node_closed and node_position == -1: open_list.insert(node) visited_node_labels = [ node.nodeLabel for _, node in enumerate(closed_list) ] visited_node_labels.append(source) if not path_found: return 'A path between the stations was not found', -1 else: cost = self._calculate_path_cost(closed_list) return visited_node_labels, cost
def transaction_heaps_add_number(self, identifier, number): """ Add a number to one of "Balanced Heaps"(self.transaction_amt_heaps) which is identified by the identifier. Due to the transaction_amt_heaps is constructed in format '{"identifier": (lower_heap, higher_heap)}', the logic to add a number is: 1) If lower_heap is empty or number < lower_heap.peek(), add number to the lower_heap; 2) Otherwise, add number to the higher_heap. Args: identifier: Identify the transaction_amt_heaps to which the number is added. The format should be 'CMTE_ID|TRANSACTION_DT' or 'CMTE_ID|ZIPCODE'. number: (float) The number to be added. """ if identifier not in self.transaction_amt_heaps: self.transaction_amt_heaps[identifier] = (heap.MaxHeap(), heap.MinHeap()) # If lower_heap is empty or the number to be added is less than lower_heap.peek(), add the number to lower_heap. if self.transaction_amt_heaps[identifier][0].empty( ) or number < self.transaction_amt_heaps[identifier][0].peek(): self.transaction_amt_heaps[identifier][0].push(number) # Otherwise, add the number to higher_heap. else: self.transaction_amt_heaps[identifier][1].push(number)
def findMedianKArr(self, arrays): arr = [] dic = {} total_len = 0 for i, ar in enumerate(arrays): total_len += len(ar) arr.append(ar[0]) if ar[0] in dic: dic[ar[0]].append(i) else: dic[ar[0]] = [i] print(arr) minH = heap.MinHeap(arr) prev = None min_ele = None for i in range(total_len // 2): min_ele = minH.extractMin() #print("min ele is :{}".format(min_ele)) #minH.printHeap() arr_index = dic[min_ele][0] dic[min_ele].remove(arr_index) ele_index = arrays[arr_index].index(min_ele) if ele_index + 1 < len(arrays[arr_index]): new_ele = arrays[arr_index][ele_index + 1] #print("new ele is :{}".format(new_ele)) minH.insert(new_ele) #minH.printHeap() if new_ele in dic: dic[new_ele].append(arr_index) else: dic[new_ele] = [arr_index] prev = min_ele if total_len % 2 == 1: return minH.getMin() else: return (prev + minH.getMin()) / 2
def heap_test(): heap = h.Heap() heap.insert(100) heap.insert(25) heap.insert(17) heap.insert(2) heap.insert(19) heap.insert(3) heap.insert(36) heap.insert(7) heap.insert(1) minheap = h.MinHeap() maxheap = h.MaxHeap() minheap.merge(heap) maxheap.merge(heap) print("------ heap ------") print("Heap Size: "+str(heap.size())) heap.pretty_print() # should print in increasing order while(not heap.empty()): print(heap.pop()) print("------ minheap ------") print("MinHeap Size: "+str(minheap.size())) minheap.pretty_print() # should print in increasing order while(not minheap.empty()): print(minheap.pop()) print("------ maxheap ------") print("MaxHeap Size: "+str(maxheap.size())) maxheap.pretty_print() # should print in decreasing order while(not maxheap.empty()): print(maxheap.pop())
#!/usr/bin/python3 import random import heap minheap = heap.MinHeap() vals = [x for x in range(0, 100)] random.shuffle(vals) for v in vals: minheap.insert(v) for x in range(0, int(len(vals) / 2)): rand_idx = random.randrange(0, len(vals)) minheap.delete(vals[rand_idx]) del vals[rand_idx] heap_list = [] min_val = minheap.extractMin() while min_val is not None: heap_list.append(min_val) min_val = minheap.extractMin() print(heap_list == sorted(vals)) minheap = heap.MinHeap(vals) heap_list = [] min_val = minheap.extractMin() while min_val is not None: heap_list.append(min_val) min_val = minheap.extractMin() print(heap_list == sorted(vals))
def find_shortest_path(self, source, goal): """Finds a shortest path between 'source' and 'goal'. Keyword arguments: source -- Either a label of a node in the graph or a 'Coordinates' object representing the coordinates of the initial position. goal -- Either a label of a node in the graph or a 'Coordinates' object representing the coordinates of the goal position. """ stationsExist = True if not isinstance(source, coordinates.Coordinates ) and not self.nodeGraph.node_exists(source): stationsExist = False if not isinstance(goal, coordinates.Coordinates ) and not self.nodeGraph.node_exists(goal): stationsExist = False if not stationsExist: return 'At least one of the specified stations does not exist' if isinstance(source, coordinates.Coordinates): source = self._find_closest_neighbour(source) if isinstance(goal, coordinates.Coordinates): goal = self._find_closest_neighbour(goal) openList = heap.MinHeap() closedList = [] sourceNode = aStarNode.AStarNode( source, self.nodeGraph.nodes[source].coordinates, -1, 0, 0) openList.insert(sourceNode) pathFound = False while not openList.empty() and not pathFound: currentNode = openList.extract_min() closedList.append(currentNode) if currentNode.nodeLabel == goal: pathFound = True continue adjacent = self._get_adjacent_nodes(currentNode, goal) for _, node in enumerate(adjacent): nodePosition = openList.get_index(node) if nodePosition != -1: if openList.nodes[nodePosition].totalCost > node.totalCost: openList.nodes[nodePosition] = node openList.bubble_up(nodePosition) else: nodeClosed = False for _, closedNode in enumerate(closedList): if node.nodeLabel == closedNode.nodeLabel: nodeClosed = True break if not nodeClosed: openList.insert(node) if currentNode.nodeLabel != goal: return 'A path between the stations was not found' else: shortestPath = [] shortestPath.append(closedList[len(closedList) - 1].nodeLabel) parentNode = closedList[len(closedList) - 1].parent if parentNode != -1: while True: shortestPath.append(parentNode) for _, node in enumerate(closedList): if node.nodeLabel == parentNode: parentNode = node.parent break if parentNode == -1: break return shortestPath[::-1]
def median_maintainance(filename): median_array = [ ] #maintain a running array of the median at each time step min_heap = heap.MinHeap( ) #use min heap to store elements larger than the current median max_heap = heap.MaxHeap( ) #use max heap to store elements smaller than the current median ##initialize data stream with open(filename, 'r') as stream: for line in stream: new_data = int(line.strip()) #print new_data if min_heap.size() == max_heap.size() == 0: #first data point median = new_data min_heap.insert(new_data) median_array.append(median) elif max_heap.size() == 0: #second data point if new_data <= min_heap.show_min(): max_heap.insert( new_data) #easy case -- new data belongs in max heap else: #complicated case -- new data belongs in min heap, but data in min heap needs to be bumped down max_heap.insert(min_heap.extract_min()) min_heap.insert(new_data) median = max( max_heap.array ) #by convention, if two heaps are equal sized median is root of max_heap median_array.append(median) else: ##load new data into the appropriate heap if new_data <= min_heap.show_min( ): #new data is in the lower half of total dataset max_heap.insert(new_data) else: min_heap.insert(new_data) #print max_heap, min_heap ##find the median if min_heap.size() == max_heap.size(): #if heaps are equally sized, median is average of two roots median = max(max_heap.array) median_array.append(median) #no rebalancing needed -- we are done with this round else: if min_heap.size() > max_heap.size(): #if min heap is bigger, median is the root of min heap rebal = min(min_heap.array) min_heap.array.remove(rebal) #rebalance the heaps by loading the former root of the min heap into the max heap max_heap.insert(rebal) else: #if max heap is bigger, median is root of max heap rebal = max(max_heap.array) max_heap.array.remove(rebal) #rebalance the heaps by loading the former root of the max heap into the min heap min_heap.insert(rebal) #if two heaps are same size after rebalancing, take mean of two roots if min_heap.size() == max_heap.size(): median = max(max_heap.array) elif min_heap.size() < max_heap.size(): median = max(max_heap.array) else: median = min(min_heap.array) median_array.append(median) print max(max_heap.array), min( min_heap.array), max_heap.size(), min_heap.size() #print 5000 in max_heap.array print sum(median_array) return sum(median_array) % 10000
minheap.print_heap('freq') z.freq = z.left.freq + z.right.freq # print 'z.freq, z.char:', z.freq, z.char minheap.insert_key(z, 'freq') minheap.print_heap('freq') return minheap.get_min() def print_tree(root, prefix): # base case if root.left is None and root.right is None and root.char.isalpha(): print root.char, ':', prefix return print_tree(root.left, prefix+'0') print_tree(root.right, prefix+'1') if __name__ == '__main__': char_list = ['f', 'e', 'c', 'b', 'd', 'a'] freq_list = [5, 9, 12, 13, 16, 45] unit_list = getUnitList(char_list, freq_list) unit_list = ['empty'] + unit_list print [unit_list[i].char for i in xrange(1, len(unit_list))] minheap = heap.MinHeap(len(unit_list)-1, unit_list) minheap.build_minheap('freq') minheap.print_heap('char') print '---------------' root_node = constructTree(minheap) print root_node.left.left.left.char print_tree(root_node, '')