def wait(self, running, tag): """Test if any worker has finished its job. If so, decrease its key and make it available """ atimer = Timer('Wait') inittime = time() status = MPI.Status() while time() - inittime < self.config['jobwait']: if world.Iprobe(source=MPI.ANY_SOURCE,tag=tag,status=status): jobf = world.recv(source=status.source, tag=tag) idx = 0 for ii, worker in enumerate(self.workers): if worker.id == status.source: idx = ii; break if self.config['verbosity'] >= 8: print('Freeing worker '+str(self.workers[idx].id)) worker = self.workers[idx] # faulty worker's job has already been cleaned if not worker.isFaulty(): del running[jobf] else: self.nActive += 1 worker.setFree() heapq._siftup(self.workers, idx)
def pushpop(self, value): item = (self.key(value), value) if self and self[0] < item: value, self[0] = self[0][1], item _siftup(self, 0) del self._indexes[value] return value
def imerge(*iterables): ''' http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/491285 Merge multiple sorted inputs into a single sorted output. Equivalent to: sorted(itertools.chain(*iterables)) >>> list(imerge([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] ''' h = [] h_append = h.append for it in map(iter, iterables): try: next = it.next h_append([next(), next]) except StopIteration: pass heapify(h) while True: try: while True: v, next = s = h[0] # raises IndexError when h is empty yield v s[0] = next() # raises StopIteration when exhausted _siftup(h, 0) # restore heap condition except StopIteration: heappop(h) # remove empty iterator except IndexError: return
def modify_key(self, index, new_key): old_key = self.heap[index][0] self.heap[index][0] = new_key if old_key > new_key: heapq._siftdown(self.heap, 0, index) elif old_key < new_key: heapq._siftup(self.heap, index)
def getSkyline(self, buildings): """ :type buildings: List[List[int]] :rtype: List[List[int]] """ points = [] for b in buildings: points.append((b[0], -b[2])) points.append((b[1], b[2])) points.sort(key=lambda x: (x[0], x[1])) # Current height prev = 0 pq = [0] results = [] for p in points: if p[1] < 0: heapq.heappush(pq, p[1]) else: if -p[1] in pq: i = pq.index(-p[1]) pq[i] = pq[-1] pq.pop() if i < len(pq): heapq._siftup(pq, i) heapq._siftdown(pq, 0, i) current = -pq[0] if prev != current: results.append((p[0], current)) prev = current return results
def delete(self, key): et = self.__expire_times.pop(key) pos = self.__expire_heap.index((et, key)) del self.__expire_heap[pos] if pos < len(self.__expire_heap): heapq._siftup(self.__expire_heap, pos) del self.__values[key]
def solve(): n = int(raw_input()) a = [] latest = [] a = map(Rev, a) heapq.heapify(a) for i in xrange(n): query = raw_input().split() if len(query) == 2: size = int(query[1]) heapq.heappush(a, Rev(size)) latest.append(size) elif query[0] == 'Q': if latest: print a[0].obj else: print "Empty" else: if latest: x = latest.pop() i = a.index(Rev(x)) a[i] = a[-1] a.pop() try: heapq._siftup(a, i) heapq._siftdown(a,0,i) except IndexError: None
def set_priority(self, priority, item, new_priority): i = self._heap.index((priority, item)) self._heap[i] = self._heap[-1] self._heap.pop() if i < len(self._heap): heapq._siftup(self._heap, i) self.push(new_priority, item)
def decrease_key(frontier, old_cost, new_cost, move): index = frontier.index((old_cost, move)) if index == len(frontier) - 1: frontier[index] = (new_cost, move) heapq._siftdown(frontier, 0, len(frontier) - 1) else: frontier[index] = frontier.pop() heapq._siftup(frontier, index) heapq.heappush(frontier,(new_cost, move))
def _remove_point(self, heights, point): for i in range(len(heights)): if (point[1]) == (heights[i]): heights[i] = heights[-1] heights.pop() if i < len(heights): heapq._siftup(heights, i) heapq._siftdown(heights, 0, i) break
def multi_delete(todo_list, indexes): """Remove the items specified by the indexes in a heap-preserving way.""" indexes = list(reversed(sorted(indexes))) for index in indexes: todo_list[index] = todo_list[-1] todo_list.pop() list_len = len(todo_list) for index in indexes: if index < list_len: heapq._siftup(todo_list, index) return todo_list
def remove_from_heapq(hq, pred): # remove all objects satisfying predicate pred from heapq hq in O(log(n)) i = 0 while i<len(hq): if pred(hq[i]): hq[i] = hq[-1] hq.pop() if i < len(hq): heapq._siftup(hq, i) continue i += 1
def heapremove(heap,item): """ Removes item from heap. (This function is missing from the standard heapq package.) """ i=heap.index(item) lastelt=heap.pop() if item==lastelt: return heap[i]=lastelt heapq._siftup(heap,i) if i: heapq._siftdown(heap,0,i)
def delete_heap(self, heap, nodeValue): leafValue = heap[-1] i = heap.index(nodeValue) if nodeValue == leafValue: heap.pop(-1) elif nodeValue <= leafValue: # similar to heappop heap[i], heap[-1] = heap[-1], heap[i] minimumValue = heap.pop(-1) if heap != []: _siftup(heap, i) else: # similar to heappush heap[i], heap[-1] = heap[-1], heap[i] minimumValue = heap.pop(-1) _siftdown(heap, 0, i)
def remove(self, value): index = None for i in range(len(self.elements)): if self.elements[i][1] == value: index = i break if index is None: return lastelt = self.elements.pop() if index == len(self.elements): return if self.elements: self.elements[index] = lastelt heapq._siftup(self.elements, index)
def cancel(self): """Unschedule this call.""" assert not self.cancelled, "Already cancelled" self.cancelled = True del self._target, self._args, self._kwargs, self._errback if self in _tasks: pos = _tasks.index(self) if pos == 0: heapq.heappop(_tasks) elif pos == len(_tasks) - 1: _tasks.pop(pos) else: _tasks[pos] = _tasks.pop() heapq._siftup(_tasks, pos)
def remove_number(self, heap, num): # find index of the num in the heap idx = heap.index(num) # copy last num to this index and del last one, so it will take O(1) time heap[idx] = heap[-1] del heap[-1] # since we have disturbed the heap # heapq.heapify(heap) if idx < len(heap): heapq._siftup(heap, idx) heapq._siftdown(heap, 0, idx)
def update(self, new_key, item): # Find then update pos, pair = self.find(item) assert pair is not None and pos is not -1 # Update the key old_key = pair[0] pair[0] = new_key # update the position # NOTE: Python's Fking implementation reverses sift up and down. if new_key < old_key: heapq._siftdown(self.heap, 0, pos) else: heapq._siftup(self.heap, pos)
def set(self, key, value, expire): try: et = self.__expire_times[key] pos = self.__expire_heap.index((et, key)) del self.__expire_heap[pos] if pos < len(self.__expire_heap): heapq._siftup(self.__expire_heap, pos) except KeyError: pass et = int(time.time() + expire) self.__expire_times[key] = et heapq.heappush(self.__expire_heap, (et, key)) self.__values[key] = value self.cleanup()
def remove(self, value): index = None for i in range(len(self.elements)): if self.elements[i][1] == value: index = i break if index is None: return lastelt = self.elements.pop() if index == len(self.elements): return self.elements[index] = lastelt heapq._siftup(self.elements, index) # https://stackoverflow.com/questions/10162679/python-delete-element-from-heap heapq._siftdown(self.elements, 0, index)
def heap_remove_at_index(heap, idx): """ Removes the element at index idx in heap with O(logN) complexity. :param heap: The heap from which the element should be removed :param idx: The index at which the element should be removed :return: The value of the removed element """ if idx == len(heap)-1: return heap.pop() result = heap[idx] heap[idx] = heap.pop() heapq._siftup(heap, idx) return result
def distance(adj, cost, s, t): n = len(adj) dist = [] prev = [] h = [] for u in range(n): if u == s: dist.append(0) else: dist.append(float("inf")) prev.append(None) heapq.heappush(h, QNode(dist[-1], u)) while h: # extract min u = heapq.heappop(h) for vi in range(len(adj[u.value])): v = adj[u.value][vi] vcost = cost[u.value][vi] if dist[v] > u.key + vcost: dist[v] = u.key + vcost prev[v] = u.value # change priority idx = [i for i,x in enumerate(h) if v == x.value] if idx: idx = idx[0] oldp = h[idx].key h[idx].key = dist[v] if dist[v] < oldp: heapq._siftdown(h, 0, idx) else: heapq._siftup(h, idx) else: heapq.heappush(h, QNode(dist[v], v)) # rebuild path v = t p = [v] directpath = False while v != None: p.insert(0, prev[v]) v = prev[v] if v == s: directpath = True #print("Path:", p) return dist[t] if directpath else -1
def find_sliding_window_median(self, nums, k): ''' Given an array of numbers and a number ‘k’, find the median of all the ‘k’ sized sub-arrays (or windows) of the array. ''' result = [] window_start = 0 min_heap, max_heap = [], [] for window_end in range(len(nums)): if not max_heap or -max_heap[0] >= nums[window_end]: heappush(max_heap, -nums[window_end]) else: heappush(min_heap, nums[window_end]) if len(max_heap) > len(min_heap) + 1: heappush(min_heap, -heappop(max_heap)) elif len(max_heap) < len(min_heap): heappush(max_heap, -heappop(min_heap)) if window_end - window_start + 1 >= k: if len(min_heap) == len(max_heap): result.append(-max_heap[0] / 2.0 + min_heap[0] / 2.0) else: result.append(-max_heap[0] / 1.0) if nums[window_start] <= -max_heap[0]: index = max_heap.index(-nums[window_start]) max_heap[index] = max_heap[-1] del max_heap[-1] if index < len(max_heap): heapq._siftup(max_heap, index) heapq._siftdown(max_heap, 0, index) else: index = min_heap.index(nums[window_start]) min_heap[index] = min_heap[-1] del min_heap[-1] if index < len(min_heap): heapq._siftup(min_heap, index) heapq._siftdown(min_heap, 0, index) if len(max_heap) > len(min_heap) + 1: heappush(min_heap, -heappop(max_heap)) elif len(max_heap) < len(min_heap): heappush(max_heap, -heappop(min_heap)) window_start += 1 return result
def main(): ll = [x + 1 for x in range(15)] print("Before: ", ll) del_idxs = [3, 4, 5, 6] for del_idx in del_idxs: print("Deleting: ", del_idx) ll[del_idx] = ll[-1] del ll[-1] if del_idx < len(ll): _siftup(ll, del_idx) _siftdown(ll, 0, del_idx) print(">> ", ll) print("After: ", ll)
def decreaseKey(self, item, priority): """ Replaces a repeated item with the minimum cost """ for i in xrange(len(self.heap)): if self.heap[i][2] == item: break isLast = i == len(self.heap) - 1 if self.heap[i][0] > priority: self.heap[i] = self.heap[-1] self.heap.pop() if not isLast: heapq._siftup(self.heap, i) heapq._siftdown(self.heap, 0, i) self.insert(item, priority)
def connectSticks(self, sticks: List[int]) -> int: if len(sticks) == 1: return sticks[0] sum = 0 heapq.heapify(sticks) while len(sticks) > 1: # num0 = heapq.heappop(sticks) num1 = heapq.heappop(sticks) sum += (num0 + num1) heapq.heappush(sticks, (num0 + num1)) heapq._siftup(sticks, len(sticks) - 1) # print(sticks) return sum
def delete(self,index): ''' 以对象id为目标在堆中删除对象,我的方法是以id找到该对象的索引,将堆中最后一个元素放到该位置, 再进行堆的调整 实验证明这么做是对的 复杂度为O(logn) :return: ''' if len(self._data)-1 == index: self._data.pop() return True self._data[index] = self._data[-1] self._data.pop() # print 'heap size is ',len(self._data), ' index ',index heapq._siftup(self._data,index) ## TODO heapq._siftdown(self._data,0,index) ## TODO 可能会有问题 ————没有问题 return True
def pop(self, index=None): """Removes the item at index and returns it, keeping the heap invariant if index is None, pops smallest element""" if index is None: val = heapq.heappop(self._heap) elif index == len(self._heap) - 1: #asking for the last element val = self._heap.pop() else: val = self._heap[index] self._heap[index] = self._heap.pop() heapq._siftup(self._heap, index) if self.key: return val[1] else: return val
def heapDelete(arr, item): if arr[-1] == item: return arr[:-1] for index, value in enumerate(arr): if value == item: leaf = arr.pop() arr[index] = leaf if item[0] < leaf[0]: heapq._siftup(arr, index) else: heapq._siftdown(arr, 0, index) break else: raise ValueError("Delete Error!") return arr
def explore(arr): minElements = [] for ele in arr: heappush(minElements, ele) print (minElements, minElements[0]) # Index # Delete a particular value from hashmap in O(1) time and O(N) time ele = 5 # O(N) time - using heapify index = minElements.index(ele) minElements[index] = minElements[-1] del minElements[-1] heapify(minElements) # O(N) # O(1) time - using _siftup and _siftdown index = minElements.index(ele) minElements[index] = minElements[-1] del minElements[-1] if index < len(minElements): _siftup(minElements, index) _siftdown(minElements, 0, index) index = minElements.index(1) print ("idx:", index) minElements[index] = minElements[-1] print (minElements, minElements[0]) del minElements[-1] print (minElements, minElements[0]) if index < len(minElements): _siftup(minElements, index) print ("1, ", minElements) _siftdown(minElements, 0, index) print ("2, ", minElements) print ("F", minElements, minElements[0]) # Popping out elements while minElements: popped = heappop(minElements) print ("Popped: ", popped)
def delete(self, val: int) -> None: # as we have sliding window, we need to delete elements, when we shrink window # choose heap heap = self.min_h if val <= -self.max_h[0]: heap = self.max_h val = -val # find element in heap idx = heap.index(val) # change it with last element in heap heap[idx], heap[len(heap) - 1] = heap[len(heap) - 1], heap[idx] heap.pop() # find position of element in heap if idx < len(heap): heapq._siftup(heap, idx) self._balance()
def reschedule(self, new_timeout: float) -> None: assert not self.is_canceled, "can't reschedule a canceled task (sanity check)" # can be removed if need be. assert self.parent, "missing parent" with self.parent.queue_lock: try: i = self.parent.task_queue.index(self) except ValueError as e: # we don't exist in the parent queue. self.timeout = new_timeout self.parent.add_task(self) return if new_timeout > self.timeout: # new larger timeout so we sift up. self.timeout = new_timeout heapq._siftup(self.parent.task_queue, i) else: self.timeout = new_timeout heapq._siftdown(self.parent.task_queue, 0, i)
def update_vertex(self, node_id, distance): old_distance = self.key_value_pair[node_id] self.key_value_pair[node_id] = distance old_distance_position_in_key = self.key_heap.index(old_distance) # The following procedure was adapted from StackOverflow # https://stackoverflow.com/questions/10162679/python-delete-element-from-heap # It was necessary to make python heap update in O(log(v)) self.key_heap[old_distance_position_in_key] = self.key_heap[-1] self.key_heap.pop() if old_distance_position_in_key < len(self.key_heap): heapq._siftup(self.key_heap, old_distance_position_in_key) heapq._siftdown(self.key_heap, 0, old_distance_position_in_key) heapq.heappush(self.key_heap, distance)
def key_bfs_precalc(entrances, dist_map, keys, doors): init_conf = (frozenset(entrances), frozenset(keys.keys())) best_conf = {init_conf: 0} heap = [(0, init_conf)] while heap: di, (pp, ke) = heapq.heappop(heap) if len(ke) == 0: return di for p in pp: #print(dist_map.keys()) for k, r in ((x, dist_map[p][x]) for x in ke if x in dist_map[p]): if len(r['blocking'] & ke) > 0: continue if len(r['blocking_key'] & ke) > 0: continue new_ke = frozenset(ke - {k}) new_di = di + r['dist'] conf = (((pp - {p}) | {keys[k]}), new_ke) prev_di = best_conf.get(conf, None) if prev_di is not None and prev_di < new_di: continue else: best_conf[conf] = new_di if prev_di is not None: for i, tup in enumerate(heap): if tup[1] == conf: new_item = (new_di, tup[1]) heap[i] = new_item # Instead of: heapq.heapify(heap) # https://stackoverflow.com/questions/10162679/python-delete-element-from-heap # Private API for heapq: heap[i] = heap[-1] heap.pop() if i < len(heap): heapq._siftup(heap, i) heapq._siftdown(heap, 0, i) heapq.heappush(heap, new_item) break else: print("Failed to replace a previously known state from heap.\nCurrent best {}, new best {}".format(best_conf[conf], new_di)) assert False continue heapq.heappush(heap, (new_di, conf))
def heap_operations(): heap = [4, 2, 1, 3] # heapify heapq.heapify(heap) # top top = heap[0] # heappop top = heapq.heappop(heap) # heappush heapq.heappush(heap, 5) # heappushpop = push + pop heapq.heappushpop(heap, 0) # heapreplace = pop + push heapq.heapreplace(heap, 0) data = [10, 5, 18, 2, 37, 3, 8, 7, 19, 1] heapq.heapify(data) old, new = 8, 22 # increase the 8 to 22 i = data.index(old) data[i] = new # _siftup, from root to leaf, when increase heapq._siftup(data, i) old, new = 10, 4 # decrease the 10 to 4 i = data.index(old) data[i] = new # _siftdown, from leaf to root, when decrease heapq._siftdown(data, 0, i) # find n largest by queue heapq.nlargest(data, 3) # find n smallest by queue heapq.nsmallest(data, 3) # Merge multiple sorted inputs into a single sorted output # e.g. merge timestamped entries from multiple log files heapq.merge([1, 3, 5, 7], [0, 2, 4, 8], [5, 10, 15, 20], [], [25])
def remove(self, val): if not self.__heap: raise KeyError(val) i = 0 n = len(self.__heap) while i < n and self.__heap[i] != val: i += 1 if i >= n: raise KeyError(val) if i == n - 1: self.__heap.pop() else: self.__heap[i] = self.__heap[-1] self.__heap.pop() heapq._siftup(self.__heap, i)
def remove(self, val): if not self.__heap: return i = 0 n = len(self.__heap) while i < n and self.__heap[i] != val: i += 1 if i == n: return if i == n - 1: self.__heap.pop() else: self.__heap[i] = self.__heap[-1] self.__heap.pop() heapq._siftup(self.__heap, i) heapq._siftdown(self.__heap, 0, i)
def __setitem__(self, pos, item): if isinstance(pos, slice): raise TypeError('Heap objects do no support slice setting') pos = self._fix_index(pos) item = self._wrap(item) lst = self._lst current = lst[pos] lst[pos] = item if item > current: # re-establish the heap invariant heapq._siftup(lst, pos) if lst[pos] != item: # item found its way below pos return while pos > 0: parentpos = (pos - 1) >> 1 parent = lst[parentpos] if parent <= item: break lst[pos] = parent pos = parentpos lst[pos] = item
def sorted_union(*iterators): """ Merge multiple sorted inputs into a single sorted output. Equivalent to: sorted(itertools.chain(*iterables)) >>> list(merge_sorted([1,3,5,7], [0,2,4,8], [5,10,15,20], [], [25])) [0, 1, 2, 3, 4, 5, 5, 7, 8, 10, 15, 20, 25] """ h = [head_iter(s) for s in iterators] h = [s for s in h if not s.done] heapify(h) while h: s = h[0] yield s.__next__() # advance the top iterator if s.done: heappop(h) # remove empty iterator else: _siftup(h, 0) # restore heap condition
def _pop(self, index): if index: last_item = super(Heap, self).pop() if index == len(self): return_item = last_item else: return_item = self[index] self[index] = last_item if self[(index - 1) >> 1] < last_item: _siftup(self, index) else: _siftdown(self, 0, index) return return_item lastelt = super(Heap, self).pop() if self: returnitem = self[0] self[0] = lastelt _siftup(self, 0) else: returnitem = lastelt return returnitem
def remove(smallMaxHeap, bigMinHeap, x): if not smallMaxHeap and not bigMinHeap: print("Wrong!") return False if x <= smallMaxHeap[0]: try: index = smallMaxHeap.index(x) except: print("Wrong!") return False if index == (len(smallMaxHeap) - 1): smallMaxHeap.pop() else: smallMaxHeap[index] = smallMaxHeap.pop() _siftup_max(smallMaxHeap, index) elif x >= smallMaxHeap[0]: try: index = bigMinHeap.index(x) except: print("Wrong!") return False if index == (len(bigMinHeap) - 1): bigMinHeap.pop() else: bigMinHeap[index] = bigMinHeap.pop() _siftup(bigMinHeap, index) # rebalance everything if len(smallMaxHeap) > (len(bigMinHeap) + 1): item = _heappop_max(smallMaxHeap) heappush(bigMinHeap, item) elif len(bigMinHeap) > (len(smallMaxHeap) + 1): item = heappop(bigMinHeap) _heappushMax(smallMaxHeap, item) return True
def kSmallestPairs(self, nums1, nums2, k): """ :type nums1: List[int] :type nums2: List[int] :type k: int :rtype: List[List[int]] """ if not nums1 or not nums2: return [] result = [] heap = [] # Optimization: append the first row on demand for i in range(len(nums1)): heap.append((nums1[i] + nums2[0], i, 0)) for i in range(k): if not heap: break top = heap[0] i = top[1] j = top[2] x = nums1[i] y = nums2[j] result.append([x, y]) j += 1 if j < len(nums2): x = nums1[i] y = nums2[j] heap[0] = (x + y, i, j) heapq._siftup(heap, 0) else: heapq.heappop(heap) return result
def imerge(*iterables): h = [] for it in map(iter, iterables): try: n = it.next # 这里对 it.next obj 进行hash,值没有意义,但是拼成 [n(), hash(n), n] 后能够简单的进行cmp, 避免对it.next 进行排序 h.append([n(), hash(n), n]) except StopIteration: pass heapq.heapify(h) while True: try: while True: v, n = s = h[0] yield v s[0] = n() heapq._siftup(h, 0) except StopIteration: heapq.heappop(h) except IndexError: return
def getSkyline(self, buildings): """ :type buildings: List[List[int]] :rtype: List[List[int]] """ hs = [] heap = [] for b in buildings: hs.append((b[0], -b[2])) hs.append((b[1], b[2])) hs.sort() ans = [] pre = cur = None for h in hs: pos = h[0] height = h[1] if height < 0: heapq.heappush(heap, height) else: i = heap.index(-height) heap[i] = heap[-1] heap.pop() if i < len(heap): heapq._siftup(heap, i) heapq._siftdown(heap, 0, i) if heap: cur = heap[0] if cur != pre: ans.append((pos, -1 * cur)) pre = cur else: ans.append((pos, 0)) return ans
def LFU_implement(inputdata, slotcount): print("\nLFU : ") n = len(inputdata) hit = 0 datas = [] # 슬롯 역할을 할 힙 for i in range(n): next_data = inputdata[i] uniqueNum = i # uniqueNum : heapq 모듈이 두번 이상의 value도 같이 정렬시켜버리므로 그것을 방지하기 위해. if next_data in [item[2] for item in datas]: # 캐시 적중 current = [item for item in datas if item[2] == next_data ][0] # next_data를 튜플의 세 번재 값(데이터값)으로 갖는 특정 튜플(슬롯) 찾기 oldIdx = datas.index(current) datas[oldIdx] = (current[0] + 1, current[1], current[2] ) # 해당 슬롯의 카운터를 1 증가 heapq._siftup(datas, oldIdx) # 힙 갱신 hit += 1 print("Round#{} -> [{}] 현재 캐쉬 상태 : {}, HIT!!".format( i + 1, next_data, [(item[2], item[0]) for item in datas])) else: # 캐시 미스 if len(datas) < slotcount: # 슬롯이 다 차지 않았을 때 heapq.heappush( datas, (1, uniqueNum, next_data)) # 슬롯에 데이터 추가. 카운터는 1로 초기화 else: # 슬롯이 다 찼을 때 heapq.heappop(datas) heapq.heappush( datas, (1, uniqueNum, next_data)) # 슬롯에 데이터 교체. 카운터는 1로 초기화 print("Round#{} -> [{}] 현재 캐쉬 상태 : {}".format( i + 1, next_data, [(item[2], item[0]) for item in datas])) print("H = {} / {} = {}".format(hit, n, hit / n)) return hit / n
def LFU_implement(inputdata,slotcount): n = len(inputdata) hit = 0 datas = [] # 슬롯 역할을 할 힙 for i in range(n): next_data = inputdata[i] uniqueNum = i # uniqueNum : heapq 모듈이 두번 이상의 value도 같이 정렬시켜버리므로 그것을 방지하기 위해. if next_data in [item[2] for item in datas]: # 캐시 적중 current = [item for item in datas if item[2] == next_data][0] # next_data를 튜플의 세 번재 값(데이터값)으로 갖는 특정 튜플(슬롯) 찾기 oldIdx = datas.index(current) datas[oldIdx]=(current[0]+1, current[1], current[2]) # 해당 슬롯의 카운터를 1 증가 heapq._siftup(datas, oldIdx) # 힙 갱신 hit += 1 else: # 캐시 미스 if len(datas) < slotcount: # 슬롯이 다 차지 않았을 때 heapq.heappush(datas, (1, uniqueNum, next_data)) # 슬롯에 데이터 추가. 카운터는 1로 초기화 else: # 슬롯이 다 찼을 때 heapq.heappop(datas) heapq.heappush(datas, (1, uniqueNum, next_data)) # 슬롯에 데이터 교체. 카운터는 1로 초기화 return hit / n
def poppush(self, value): return_value = self[0][1] self[0] = (self.key(value), value) _siftup(self, 0) del self._indexes[return_value] return return_value
def pushpop(self, value): if self and self[0] < value: value, self[0] = self[0], value _siftup(self, 0) del self._indexes[value] return value
def poppush(self, value): return_value = self[0] self[0] = value _siftup(self, 0) del self._indexes[return_value] return return_value
def delete_nth(heap, n): heap[n] = heap[-1] heap.pop() if n < len(heap) - 1: heapq._siftup(heap, n)
else: heapq.heappush(rightHeap,number) print(heapElement(leftHeap,rightHeap)) else: #Check if the element exists in both the heaps leftExists = True rightExists = True try: removeIndex = leftHeap.index(-number) except: leftExists = False if(leftExists == True): leftHeap[removeIndex] = leftHeap[-1] leftHeap.pop() try: heapq._siftup(leftHeap,removeIndex) except: heapq.heapify(leftHeap) if(leftExists == False): try: removeIndex = rightHeap.index(number) except: rightExists = False if(rightExists == True): rightHeap[removeIndex] = rightHeap[-1] rightHeap.pop() try: heapq._siftup(rightHeap,removeIndex) except: heapq.heapify(rightHeap) #Python siftup heap function removes the element in log(n) rather than O(n)