Estoy buscando una implementación .NET de una cola de prioridad o estructura de datos de montón
Las colas de prioridad son estructuras de datos que proporcionan más flexibilidad que la simple clasificación, ya que permiten que nuevos elementos ingresen a un sistema a intervalos arbitrarios. Es mucho más rentable insertar un nuevo trabajo en una cola prioritaria que volver a ordenar todo en cada llegada.
La cola de prioridad básica admite tres operaciones principales:
- Insertar (Q, x). Dado un elemento x con la clave k, insértelo en la cola de prioridad Q.
- Buscar-Mínimo (Q). Devuelva un puntero al elemento cuyo valor de clave es menor que cualquier otra clave en la cola de prioridad Q.
- Eliminar-Mínimo (Q). Elimine el elemento de la cola de prioridad Q cuya clave es mínima
A menos que esté buscando en el lugar equivocado, no hay ninguno en el marco. ¿Alguien sabe de uno bueno, o debo rodar el mío?
c#
.net
data-structures
heap
priority-queue
Doug McClean
fuente
fuente
Respuestas:
Me gusta usar las clases
OrderedBag
yOrderedSet
en PowerCollections como colas de prioridad.fuente
Puede que le guste IntervalHeap de la Biblioteca de colecciones genéricas C5 . Para citar la guía del usuario
La API es lo suficientemente simple
Instalar desde Nuget https://www.nuget.org/packages/C5 o GitHub https://github.com/sestoft/C5/
fuente
Aquí está mi intento de un montón .NET
Algunas pruebas:
fuente
IEqualityComparer<T>
no sería suficiente, ya que eso solo le diría si dos elementos son iguales, mientras que necesita saber la relación entre ellos (quién es más pequeño / más grande). SinIComparer<T>
embargo, es cierto que podría haber usado ...Aquí hay uno que acabo de escribir, tal vez no está tan optimizado (solo usa un diccionario ordenado) pero es fácil de entender. puede insertar objetos de diferentes tipos, por lo que no hay colas genéricas.
fuente
Encontré uno de Julian Bucknall en su blog aquí: http://www.boyet.com/Articles/PriorityQueueCSharp3.html
Lo modificamos ligeramente para que los elementos de baja prioridad en la cola eventualmente 'subieran' a la cima con el tiempo, para que no sufrieran hambre.
fuente
Como se menciona en Microsoft Collections para .NET , Microsoft ha escrito (y compartido en línea) 2 clases internas de PriorityQueue dentro de .NET Framework. Su código está disponible para probar.
EDITAR: Como comentó @ mathusum-mut, hay un error en una de las clases internas de PriorityQueue de Microsoft (la comunidad SO, por supuesto, ha proporcionado soluciones): ¿ Error en el PriorityQueue <T> interno de Microsoft?
fuente
PriorityQueue<T>
en la fuente compartida de Microsoft están marcadas con uninternal
especificador de acceso. Por lo tanto, solo los utilizan las funcionalidades internas del marco. No están disponibles para el consumo general simplemente al referirsewindowsbase.dll
a un proyecto de C #. La única forma es copiar la fuente compartida en el proyecto dentro de un archivo de clase.Puede encontrar útil esta implementación: http://www.codeproject.com/Articles/126751/Priority-queue-in-Csharp-with-help-of-heap-data-st.aspx
es genérico y se basa en la estructura de datos del montón
fuente
fácil.
fuente
for (var n2 = n / 2; n > 0 && comparer.Compare(v, heap[n2]) > 0; n = n2, n2 /= 2) heap[n] = heap[n2];
y me pregunto si valió la penaUse un traductor de Java a C # en la implementación de Java (java.util.PriorityQueue) en el marco de Java Collections, o use de manera más inteligente el algoritmo y el código central y conéctelo a una clase de C # propia que se adhiera al marco de C # Collections API para colas, o al menos colecciones.
fuente
AlgoKit
Escribí una biblioteca de código abierto llamada AlgoKit , disponible a través de NuGet . Contiene:
El código ha sido ampliamente probado. Definitivamente te recomiendo que lo pruebes.
Ejemplo
¿Por qué esos tres montones?
La elección óptima de implementación depende en gran medida de la entrada, como muestran Larkin, Sen y Tarjan en un estudio empírico de regreso a lo básico de colas prioritarias , arXiv: 1403.0252v1 [cs.DS] . Probaron montones d-ary implícitos, montones de pares, montones de Fibonacci, montones binomiales, montones d-ary explícitos, montones de pares de rango, montones de terremotos, montones de violación, montones débiles relajados y montones estrictos de Fibonacci.
AlgoKit presenta tres tipos de montones que parecen ser más eficientes entre los probados.
Sugerencia sobre la elección
Para un número relativamente pequeño de elementos, es probable que le interese usar montones implícitos, especialmente montones cuaternarios (4 arios implícitos). En caso de operar en tamaños de almacenamiento dinámico más grandes, las estructuras amortizadas como los montones binomiales y los montones de pares deberían funcionar mejor.
fuente
Aquí está otra implementación del equipo de NGenerics:
NGenerics PriorityQueue
fuente
Tuve el mismo problema recientemente y terminé creando un paquete NuGet para esto.
Esto implementa una cola de prioridad estándar basada en el montón. También tiene todas las sutilezas habituales de las colecciones BCL:
ICollection<T>
eIReadOnlyCollection<T>
implementación,IComparer<T>
soporte personalizado , capacidad para especificar una capacidad inicial y unDebuggerTypeProxy
hacer que la colección sea más fácil de trabajar en el depurador.También hay una versión en línea del paquete que simplemente instala un único archivo .cs en su proyecto (útil si desea evitar tomar dependencias visibles desde el exterior).
Hay más información disponible en la página de github .
fuente
Una implementación simple de Max Heap.
https://github.com/bharathkumarms/AlgorithmsMadeEasy/blob/master/AlgorithmsMadeEasy/MaxHeap.cs
fuente
La siguiente implementación de un
PriorityQueue
usosSortedSet
de la biblioteca del sistema.fuente
T x
y quéK key
? Supongo que este es un truco para permitir duplicadosT x
, y necesito generar una clave única (por ejemplo, UUID).