Python inclui o módulo heapq para min-heaps, mas eu preciso de um heap máximo. O que devo usar para uma implementação de heap máximo no Python?
python
data-structures
heap
recursive-datastructures
Douglas Mayle
fonte
fonte
heapq
não fornece um reverso.heapq
e que não haja uma boa alternativa.int
/float
, pode inverter a ordem envolvendo-os em uma classe com um__lt__
operador invertido .Você pode usar
Se você deseja exibir elementos, use:
fonte
_heapify_max
,_heappushpop_max
,_siftdown_max
, e_siftup_max
.A solução é negar seus valores quando você os armazena na pilha ou inverte a comparação de objetos da seguinte maneira:
Exemplo de um heap máximo:
Mas você deve se lembrar de agrupar e desembrulhar seus valores, o que requer saber se você está lidando com um heap mínimo ou máximo.
Classes MinHeap, MaxHeap
Adicionar classes
MinHeap
eMaxHeap
objetos pode simplificar seu código:Exemplo de uso:
fonte
list
parâmetro opcional a __init__, nesse caso eu chamoheapq.heapify
e também adicionei umheapreplace
método.A solução mais fácil e ideal
Ai está. Todos os números mais altos agora são os mais baixos e vice-versa.
Lembre-se de que quando você popula um elemento para multiplicá-lo por -1, a fim de obter o valor original novamente.
fonte
Eu implementei uma versão de heap max do heapq e a enviei ao PyPI. (Alteração muito pequena do código CPython do módulo heapq.)
https://pypi.python.org/pypi/heapq_max/
https://github.com/he-zhe/heapq_max
Instalação
Uso
tl; dr: o mesmo que o módulo heapq, exceto a adição de '_max' a todas as funções.
fonte
Se você estiver inserindo chaves comparáveis, mas não parecidas com int, você pode potencialmente substituir os operadores de comparação nelas (por exemplo, <= torne-se> e> torna-se <=). Caso contrário, você poderá substituir o heapq._siftup no módulo heapq (no final, tudo é apenas código Python).
fonte
# If available, use C implementation
) que faz exatamente o que o comentário descreve.Permitindo que você escolha uma quantidade arbitrária de itens maiores ou menores
fonte
Estender a classe int e substituir __lt__ é uma das maneiras.
fonte
Criei um invólucro de heap que inverte os valores para criar um heap máximo, bem como uma classe de invólucro para um min-heap para tornar a biblioteca mais parecida com OOP. Aqui está a essência. Existem três classes; Heap (classe abstrata), HeapMin e HeapMax.
Métodos:
fonte
Caso você queira obter o maior elemento K usando o max heap, execute o seguinte truque:
fonte
nlargest
aqui -> github.com/python/cpython/blob/…Seguindo a excelente resposta de Isaac Turner , gostaria de colocar um exemplo com base em K pontos mais próximos da origem usando max heap.
fonte
Para elaborar em https://stackoverflow.com/a/59311063/1328979 , aqui está uma implementação do Python 3 totalmente documentada, anotada e testada para o caso geral.
https://gist.github.com/marccarre/577a55850998da02af3d4b7b98152cf4
fonte
Esta é uma
MaxHeap
implementação simples baseada emheapq
. Embora funcione apenas com valores numéricos.Uso:
fonte