web-dev-qa-db-ja.com

Pythonの最大ヒープ実装には何を使用しますか?

Pythonには、最小ヒープ用のheapqモジュールが含まれていますが、最大ヒープが必要です。 Pythonの最大ヒープ実装には何を使用すればよいですか?

179
Douglas Mayle

最も簡単な方法は、キーの値を反転し、heapqを使用することです。たとえば、1000.0を-1000.0に、5.0を-5.0に変更します。

179

使用できます

import heapq
listForTree = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]    
heapq.heapify(listForTree)             # for a min heap
heapq._heapify_max(listForTree)        # for a maxheap!!

要素をポップしたい場合は、次を使用します。

heapq.heappop(minheap)      # pop from minheap
heapq._heappop_max(maxheap) # pop from maxheap
169
Lijo Joseph

解決策は、値をヒープに格納するときに値を無効にするか、オブジェクトの比較を次のように逆にすることです。

import heapq

class MaxHeapObj(object):
  def __init__(self,val): self.val = val
  def __lt__(self,other): return self.val > other.val
  def __eq__(self,other): return self.val == other.val
  def __str__(self): return str(self.val)

最大ヒープの例:

maxh = []
heapq.heappush(maxh,MaxHeapInt(x))
x = maxh[0].val # fetch max value
x = heapq.heappop(maxh).val # pop max value

ただし、値をラップおよびアンラップすることを覚えておく必要があります。これには、最小ヒープまたは最大ヒープのどちらを扱っているかを知る必要があります。

MinHeap、MaxHeapクラス

MinHeapおよびMaxHeapオブジェクトのクラスを追加すると、コードを簡素化できます。

class MinHeap(object):
  def __init__(self): self.h = []
  def heappush(self,x): heapq.heappush(self.h,x)
  def heappop(self): return heapq.heappop(self.h)
  def __getitem__(self,i): return self.h[i]
  def __len__(self): return len(self.h)

class MaxHeap(MinHeap):
  def heappush(self,x): heapq.heappush(self.h,MaxHeapObj(x))
  def heappop(self): return heapq.heappop(self.h).val
  def __getitem__(self,i): return self.h[i].val

使用例:

minh = MinHeap()
maxh = MaxHeap()
# add some values
minh.heappush(12)
maxh.heappush(12)
minh.heappush(4)
maxh.heappush(4)
# fetch "top" values
print(minh[0],maxh[0]) # "4 12"
# fetch and remove "top" values
print(minh.heappop(),maxh.heappop()) # "4 12"
46
Isaac Turner

最も簡単で理想的なソリューション

値に-1を掛けます

行くぞ現在、すべての最高数は最低であり、その逆も同様です。

元の値を再度取得するために、要素をポップして-1を乗算することを覚えておいてください。

20

比較可能であるがint型ではないキーを挿入する場合、それらの比較演算子をオーバーライドする可能性があります(つまり、<=になる>および>が<=になる)。それ以外の場合は、heapqモジュールでheapq._siftupをオーバーライドできます(最終的にはPythonコードのみです)。

4
rlotun

任意の量の最大または最小アイテムを選択できるようにする

import heapq
heap = [23, 7, -4, 18, 23, 42, 37, 2, 8, 2, 23, 7, -4, 18, 23, 42, 37, 2]
heapq.heapify(heap)
print(heapq.nlargest(3, heap))  # [42, 42, 37]
print(heapq.nsmallest(3, heap)) # [-4, -4, 2]
4
jasonleonhard

Heapqの最大ヒープバージョンを実装し、PyPIに送信しました。 (heapqモジュールのCPythonコードのわずかな変更。)

https://pypi.python.org/pypi/heapq_max/

https://github.com/he-zhe/heapq_max

Installation

pip install heapq_max

使用法

tl; dr:すべての関数に「_max」を追加する以外はheapqモジュールと同じです。

heap_max = []                           # creates an empty heap
heappush_max(heap_max, item)            # pushes a new item on the heap
item = heappop_max(heap_max)            # pops the largest item from the heap
item = heap_max[0]                      # largest item on the heap without popping it
heapify_max(x)                          # transforms list into a heap, in-place, in linear time
item = heapreplace_max(heap_max, item)  # pops and returns largest item, and
                                    # adds new item; the heap size is unchanged
2
Zhe He

Intクラスを拡張し、_ LT _をオーバーライドすることは方法の1つです。

import queue
class MyInt(int):
    def __lt__(self, other):
        return self > other

def main():
    q = queue.PriorityQueue()
    q.put(MyInt(10))
    q.put(MyInt(5))
    q.put(MyInt(1))
    while not q.empty():
        print (q.get())


if __== "__main__":
    main()
1
Gaurav

値を反転して最大ヒープを作成するヒープラッパーと、ライブラリをよりOOP風にするための最小ヒープのラッパークラスを作成しました。 ここ は要点です。 3つのクラスがあります。ヒープ(抽象クラ​​ス)、HeapMin、およびHeapMax。

方法:

isempty() -> bool; obvious
getroot() -> int; returns min/max
Push() -> None; equivalent to heapq.heappush
pop() -> int; equivalent to heapq.heappop
view_min()/view_max() -> int; alias for getroot()
pushpop() -> int; equivalent to heapq.pushpop
0