2011-08-07 16 views
52

Parece haber varias implementaciones de cola de prioridad disponibles para Haskell. Por ejemplo, hay:Comparación de implementaciones de cola de prioridad en Haskell

ambos de los cuales parece ser pura cola de prioridad de los datos estructuras. El primero se basa en árboles de dedo, una estructura de datos con la que no estoy familiarizado; el último es un contenedor alrededor de Data.Map. También hay

que define estructuras datos montón puramente funcional de la que uno trivialmente puede hacer colas de prioridad. . También hay

la que tanto implementar montones meldable puramente funcionales utilizando los datos Brodal/Okasaki estructura, que creo que es análoga a la estructura de datos de montón binomial en tierra funcional no pura.

(Ah, y también hay

  • Data.PriorityQueue (en prioridad-cola-0.2.2 en hackage)

cuya función es claro para mí, pero que parece estar relacionado crear colas de prioridad adjuntas a una mónada, y que parece construirse encima de Data.Map de todos modos. En esta pregunta, me preocupan las colas de prioridad puramente funcionales, así que creo que el paquete priority-queue-0.2.2 es irrelevante . ¡Pero corríjame si estoy equivocado!)

Necesito una estructura de datos de cola de prioridad pura y funcional para un proyecto que estoy construyendo. Me preguntaba si alguien podría dar algunas palabras de sabiduría cuando decida entre el embarrassment of riches proporcionado por hackage. Específicamente:

  1. Supongamos que quiero hacer funciones aparte de las operaciones tradicionales de inserción de cola y extracción-mínimo, en una presentación puramente funcional/inmutable. ¿Cuáles son los pros y los contras de los paquetes mencionados anteriormente? ¿Alguien tiene experiencia en usar cualquiera de ellos 'enojado'? ¿Cuáles son las compensaciones en el rendimiento? ¿Confiabilidad? ¿Cuáles son usados ​​más ampliamente por otros? (Usar esos puede hacer que mi código sea más fácil de leer para otros, ya que es más probable que estén familiarizados con la biblioteca). ¿Hay alguna otra cosa que deba saber antes de tomar una decisión entre ellos?
  2. Si también quiero una fusión eficiente de las colas de prioridad, ¿entonces qué? (No lo hago para este proyecto, pero pensé en agregar esto pero haría que la pregunta SO sea más útil para futuros lectores.)
  3. ¿Hay algún otro paquete de cola de prioridad por ahí que me haya perdido?
+3

"finger trees, una estructura de datos con la que no estoy familiarizado" Le recomiendo leer el artículo http://www.soi.city.ac.uk/~ross/papers/FingerTree.html: es muy claramente escrito y la estructura de datos es ampliamente útil. La cola de prioridad se analiza específicamente, entre otras aplicaciones. –

+3

Soy el autor de 'priority-queue-0.2.2' - fue uno de mis primeros intentos en Haskell y aunque nunca he encontrado o me han notificado problemas con esa versión, es casi seguro que no como bien pensado como los demás. Su propósito es de hecho para su uso principalmente con IORef, STRef, et al. Se podría usar en State/StateT para una interfaz "pura", pero realmente no vale la pena hacerlo cuando hay tantas otras opciones (incluso simplemente "Mapa", que tiene "minView" y "maxView"). 'funciones). – mokus

Respuesta

33

Hay una gran cantidad de implementaciones de cola de prioridad que debe conocer en hackage, sólo para completar su lista:

De aquellos que encontré, PSQueue tiene una interfaz especialmente agradable. Supongo que fue una de las primeras implementaciones y está muy bien cubierto en this paper por Ralf Hinze. Puede que no sea la implementación más eficiente y completa, pero hasta ahora ha cumplido todas mis necesidades.

Hay un artículo muy bueno en el MonadReader (issue 16) de Louis Wassermann (que también escribió el paquete pqueue). En su artículo, Louis ofrece una variedad de implementaciones de colas de prioridad diferentes y también incluye complejidades algorítmicas para cada una.
Como un ejemplo sorprendente de la simplicidad de algunas colas de prioridad interna, incluye algunas pequeñas implementaciones geniales. Mi favorito (tomado de su artículo):

data SkewHeap a = Empty | SkewNode a (SkewHeap a) (SkewHeap a) deriving (Show) 

(+++) :: Ord a => SkewHeap a -> SkewHeap a -> SkewHeap a 
[email protected](SkewNode x1 l1 r1) +++ [email protected](SkewNode x2 l2 r2) 
    | x1 <= x2 = SkewNode x1 (heap2 +++ r1) l1 
    | otherwise = SkewNode x2 (heap1 +++ r2) l2 
Empty +++ heap = heap 
heap +++ Empty = heap 

extractMin Empty = Nothing 
extractMin (SkewNode x l r) = Just (x , l +++ r) 

poca implementación fresca ... un breve ejemplo de uso:

test = foldl (\acc x->acC+++ x) Empty nodes 
    where nodes = map (\x-> SkewNode x Empty Empty) [3,5,1,9,7,2] 

Algunos referentes de las implementaciones de cola de prioridad se puede encontrar here y de una forma bastante interesante thread en haskell.org here.

+1

+1 por mencionar el artículo de Monad.Reader, que encontré muy útil. –

+0

Solo 3 de las anteriores son búsquedas prioritarias * que también permiten operaciones como 'actualizar' o' eliminar' de entradas. Para aquellos que creé un currículum y puntos de referencia en este [hilo de la lista de correo de Haskell] (http://thread.gmane.org/gmane.comp.lang.haskell.general/19734). – nh2

+0

Sería bueno saber cuáles de los elementos duplicados de soporte en la cola de prioridad. También compatible con operaciones Max y Min –

Cuestiones relacionadas