Python incluye el módulo heapq para montones mínimos, pero necesito un montón máximo. ¿Qué debo usar para una implementación max-heap en Python?
python
data-structures
heap
recursive-datastructures
Douglas Mayle
fuente
fuente
heapq
que no proporcione un reverso.heapq
, y que no haya una buena alternativa.int
/float
, puede invertir el orden envolviéndolos en una clase con un__lt__
operador invertido .Puedes usar
Si luego quieres hacer estallar elementos, usa:
fuente
_heapify_max
,_heappushpop_max
,_siftdown_max
, y_siftup_max
.La solución es negar sus valores cuando los almacena en el montón, o invertir su comparación de objetos de la siguiente manera:
Ejemplo de un montón máximo:
Pero debe recordar envolver y desenvolver sus valores, lo que requiere saber si se trata de un montón mínimo o máximo.
Clases MinHeap, MaxHeap
Agregar clases para
MinHeap
yMaxHeap
objetos puede simplificar su código:Ejemplo de uso:
fuente
list
parámetro opcional a __init__ en cuyo caso llamoheapq.heapify
y también agregué unheapreplace
método.La solución más fácil e ideal.
Ahí tienes. Todos los números más altos son ahora los más bajos y viceversa.
Solo recuerde que cuando hace estallar un elemento para multiplicarlo por -1 para obtener el valor original nuevamente.
fuente
Implementé una versión heap max de heapq y la envié a PyPI. (Muy ligero cambio del código CPython del módulo heapq.)
https://pypi.python.org/pypi/heapq_max/
https://github.com/he-zhe/heapq_max
Instalación
Uso
tl; dr: igual que el módulo heapq excepto que agrega '_max' a todas las funciones.
fuente
Si está insertando claves que son comparables pero no de tipo int, podría anular los operadores de comparación (es decir, <= convertirse> y> se convierte en <=). De lo contrario, puede anular heapq._siftup en el módulo heapq (al final, todo es solo código Python).
fuente
# If available, use C implementation
) que hace exactamente lo que describe el comentario.Permitiéndole elegir una cantidad arbitraria de artículos más grandes o más pequeños
fuente
Ampliar la clase int y anular __lt__ es una de las formas.
fuente
He creado un contenedor de montón que invierte los valores para crear un montón máximo, así como una clase de contenedor para un montón mínimo para hacer que la biblioteca sea más parecida a OOP. Aquí está la esencia. Hay tres clases; Heap (clase abstracta), HeapMin y HeapMax.
Métodos:
fuente
En caso de que desee obtener el elemento K más grande utilizando el montón máximo, puede hacer el siguiente truco:
fuente
nlargest
aquí -> github.com/python/cpython/blob/…Siguiendo la excelente respuesta de Isaac Turner , me gustaría poner un ejemplo basado en K Puntos más cercanos al origen usando el montón máximo.
fuente
Para profundizar en https://stackoverflow.com/a/59311063/1328979 , aquí hay una implementación de Python 3 completamente documentada, comentada y probada para el caso general.
https://gist.github.com/marccarre/577a55850998da02af3d4b7b98152cf4
fuente
Esta es una
MaxHeap
implementación simple basada enheapq
. Aunque solo funciona con valores numéricos.Uso:
fuente