Сравнение реализаций очереди приоритетов в Haskell


там, кажется, есть несколько приоритетных реализаций очереди, доступных в готовом виде для Haskell. Например, здесь:

оба из которых кажутся чистыми приоритетными структурами данных очереди. Первый основан на пальцевых деревьях, структуре данных, с которой я незнакомый; последний является оболочкой вокруг данных.Карта. Там же

который определяет чисто функциональные структуры данных кучи, из которых можно тривиально сделать приоритетные очереди. . Есть еще

, который обе реализуйте чисто функциональные плавящиеся кучи, используя структуру данных Brodal/Okasaki, которая, как я считаю, аналогична биномиальной структуре данных кучи в нечистой функциональной земле.

(О, и еще

  • данные.PriorityQueue (in priority-queue-0.2.2 on hackage)

чья функция мне непонятна, но которая, похоже, связана с построением очередей приоритетов, прикрепленных к монаде, и которая, похоже, построена поверх данных.Карта в любом случае. В этом вопрос, я занимаюсь чисто функциональными очередями приоритетов, поэтому я думаю, что пакет priority-queue-0.2.2 не имеет значения. Но поправьте меня, если я ошибаюсь!)

Мне нужна чистая функциональная структура данных очереди приоритетов для проекта, который я строю. Мне было интересно, может ли кто-нибудь предоставить какие-либо слова мудрости, когда я решаю между слишком много предоставлены здесь. В частности:

  1. предположим, я хочу сделать функции помимо традиционных приоритетные операции вставки очереди и извлечения-min, в чисто функциональном / неизменяемом представлении. Каковы плюсы и минусы упомянутых выше пакетов? У кого-нибудь есть опыт использования любого из них "в гневе"? Каковы компромиссы в производительности? Надежность? Которые используются более широко другими? (Используя их, вы можете сделать мой код более легким для чтения другими, так как они, скорее всего, будут знакомы с библиотекой.) Есть какие-то другие вещи, которые я должен знать, прежде чем принимать решение между ними?
  2. Если я также хочу эффективного слияния очередей приоритетов, что тогда? (Я не для этого проекта, но я думал добавить это, но сделал бы так вопрос более полезным для будущих читателей.)
  3. есть ли другие приоритетные пакеты очереди там, что я пропустил?
1 54

1 ответ:

существует множество реализаций очереди приоритетов, которые можно найти на hackage, просто чтобы завершить ваш список:

из из них я обнаружил, что PSQueue имеет особенно приятный интерфейс. Я думаю, что это была одна из первых реализаций и красиво покрыта этой статье Ральф Гинц. Возможно, это не самая эффективная и полная реализация, но до сих пор она удовлетворяла все мои потребности.

в MonadReader есть очень хорошая статья (выпуск 16) Луи Вассерман (который также написал pqueue пакет). В своей статье Луи дает множество различных приоритетные реализации очереди, а также включает в себя алгоритмические сложности для каждого.
В качестве яркого примера простоты некоторых внутренних приоритетов очереди он включает в себя некоторые интересные небольшие реализации. Мой любимый (взятый из его статьи):

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

(+++) :: Ord a => SkewHeap a -> SkewHeap a -> SkewHeap a
heap1@(SkewNode x1 l1 r1) +++ heap2@(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 )

прохладно мало реализации...короткий пример использования:

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

можно найти некоторые критерии реализации приоритетных очередей здесь и в довольно интересном thread on haskell.org здесь.