Jump to content

Куча сопряжения

Парная куча — это тип кучи структуры данных с относительно простой реализацией и превосходной практической амортизированной производительностью, представленный Майклом Фредманом , Робертом Седжвиком , Дэниелом Слиатором и Робертом Тарджаном в 1986 году. [1] Парные кучи представляют собой , упорядоченные по куче многонаправленные древовидные структуры , и их можно считать упрощенными кучами Фибоначчи . Они считаются «надежным выбором» для реализации таких алгоритмов, как алгоритм MST Прима , [2] и поддерживают следующие операции (при условии минимальной кучи):

  • find-min : просто вернуть верхний элемент кучи.
  • meld : сравнить два корневых элемента, меньший остается корнем результата, больший элемент и его поддерево добавляются как дочерние элементы этого корня.
  • Insert : создать новую кучу для вставленного элемента и объединить ее с исходной кучей.
  • уменьшите-ключ (необязательно): удалите поддерево, основанное на ключе, который нужно уменьшить, замените ключ меньшим ключом, затем объедините результат обратно в кучу.
  • delete-min : удалить корень и выполнять повторные объединения его поддеревьев, пока не останется одно дерево. Используются различные стратегии слияния.

Анализ временной сложности парных куч изначально был вдохновлен анализом расширенных деревьев . [1] Амортизированное время на одну минуту удаления равно O (log n ) , а операции find-min , meld и вставки выполняются за время O (1) . [3]

Когда также добавляется операция уменьшения ключа , определение точного асимптотического времени работы спариваемых куч оказывается затруднительным. Первоначально временная сложность этой операции предполагалась на эмпирических основаниях равной O (1) , [4] но Фредман доказал, что амортизированное время на одну клавишу уменьшения не менее для некоторых последовательностей операций. [5] Используя другой аргумент амортизации, Петти затем доказал, что команды Insert , Meld и уменьшать-ключи работают в амортизированное время, которое . [6] Позже Элмасри представил разработку парных куч (ленивая, консолидация), для которых с уменьшающим ключом . выполняются прогоны амортизированное время и другие операции имеют оптимальные амортизированные границы, [7] [8] но не туго Bound известен исходной структурой данных. [3] [6]

Хотя асимптотическая производительность парных куч хуже, чем у других алгоритмов очереди с приоритетами, таких как кучи Фибоначчи , которые выполняют уменьшение ключа в амортизированное время, производительность на практике отличная. Джонс [9] и Ларкин, Сен и Тарьян [10] проводил эксперименты по объединению куч и других структур данных кучи. Они пришли к выводу, что d-арные кучи, такие как двоичные кучи, работают быстрее, чем все другие реализации кучи, когда операция уменьшения ключа не требуется (и, следовательно, нет необходимости внешне отслеживать расположение узлов в куче), но что при уменьшении -ключ. Требуется Парные кучи часто работают быстрее, чем d-арные кучи, и почти всегда быстрее, чем другие кучи на основе указателей, включая структуры данных, такие как кучи Фибоначчи , которые теоретически более эффективны. Чен и др. [11] исследовал очереди приоритетов специально для использования с алгоритмом Дейкстры и пришел к выводу, что в обычных случаях использование d-арной кучи без ключа уменьшения (вместо дублирования узлов в куче и игнорирования избыточных экземпляров) приводит к повышению производительности, несмотря на худшие теоретические гарантии производительности.

Структура [ править ]

Куча спаривания — это либо пустая куча, либо дерево спаривания, состоящее из корневого элемента и, возможно, пустого списка деревьев спаривания. Свойство упорядочения кучи требует, чтобы родительский элемент любого узла был не больше самого узла. Следующее описание предполагает чисто функциональную кучу, которая не поддерживает операцию уменьшения ключа .

тип  PairingTree[Elem] = Куча(elem: Elem, подкучи: List[PairingTree[Elem]]) введите  PairingHeap[Elem] = Empty | СопряжениеДерево[Элем] 

Реализация на основе указателей для машин с оперативной памятью , поддерживающая уменьшение ключа , может быть достигнута с использованием трех указателей на каждый узел, представляя дочерние элементы узла двусвязным списком : указатель на первого дочернего узла узла, один на его следующего родственного брата. и один — его предыдущему брату (или, если самый левый брат, его родителю). Его также можно рассматривать как вариант двоичного дерева с левым дочерним и правым сестринским элементом с дополнительным указателем на родителя узла (который представляет его предыдущего родственного узла или фактического родителя для самого левого родственного узла). Альтернативно, указатель предыдущего элемента можно опустить, позволив последнему дочернему элементу указывать обратно на родительский элемент, если добавлен один логический флаг, обозначающий «конец списка». Это обеспечивает более компактную структуру за счет постоянного коэффициента накладных расходов на каждую операцию. [1]

Операции [ править ]

Слиться [ править ]

Объединение с пустой кучей возвращает другую кучу, в противном случае возвращается новая куча, имеющая минимум из двух корневых элементов в качестве корневого элемента и просто добавляющая кучу с большим корнем в список подкуч:

функция  meld(heap1, heap2: PairingHeap[Elem]) -> PairingHeap[Elem]     если  куча1 пуста         вернуть  кучу2     elsif  heap2 пуст         вернуть  кучу1     elsif  heap1.elem < heap2.elem         return  Heap(heap1.elem, heap2 :: heap1.subheaps)     иначе          return  Heap(heap2.elem, heap1 :: heap2.subheaps) 

Вставить [ править ]

Самый простой способ вставить элемент в кучу — объединить кучу с новой кучей, содержащей только этот элемент и пустой список подкуч:

функция  вставки(elem: Elem, куча: PairingHeap[Elem]) -> PairingHeap[Elem]     return  meld(Куча(elem, []), куча) 

Найти-мин [ править ]

Функция find-min просто возвращает корневой элемент кучи:

функция  find-min(куча: PairingHeap[Elem]) -> Elem     если  куча пуста         ошибка      иначе          вернуть  кучу.елем 

Удалить-мин [ изменить ]

Единственная нетривиальная фундаментальная операция — удаление минимального элемента из кучи. Это требует выполнения повторных объединений дочерних элементов до тех пор, пока не останется только одно дерево. Стандартная стратегия сначала объединяет подкучи в пары (это шаг, который дал название этой структуре данных) слева направо, а затем объединяет результирующий список куч справа налево:

функция  delete-min(куча: PairingHeap[Elem]) -> PairingHeap[Elem]     если  куча пуста         ошибка      , иначе          верните  пары слияния (куча.подкучи) 

При этом используется вспомогательная функция merge-pairs :

функция  merge-pairs(list: List[PairingTree[Elem]]) -> PairingHeap[Elem]     если  длина (список) == 0         вернуть  Пусто     длина elsif  (список) == 1         список возврата  [0]     иначе          return  meld(meld(list[0], list[1]), merge-pairs(list[2..])) 

То, что это действительно реализует описанную стратегию слияния с двумя проходами слева направо, а затем справа налево, можно увидеть из этого сокращения:

 пары слияния ([H1, H2, H3, H4, H5, H6, H7])=> meld(meld(H1, H2), слияние пар([H3, H4, H5, H6, H7]))     # объединяем H1 и H2 с H12, затем оставшуюся часть списка=> объединение(  H12  , объединение(объединение(H3, H4), объединение пар([H5, H6, H7])))     # объединить H3 и H4 с H34, а затем остальную часть списка=> объединить(H12, объединить(  H34  , объединить(объединить(H5, H6), объединить пары([H7]))))     # объединить H5 и H6 с H56, а затем оставшуюся часть списка=> объединить(H12, объединить(H34, объединить(  H56  , H7)))     # переключить направление, объединить две последние получившиеся кучи, получив H567=> объединить (H12, объединить (H34,  H567  ))     # объединяем две последние кучи, получая H34567=> объединить (H12,  H34567  )      # наконец, объединяем первую пару с результатом слияния остальных=>  H1234567 

Сводка времени работы [ править ]

Вот временные сложности [12] различных структур данных кучи. Имена функций предполагают минимальную кучу. Значение « O ( f )» и « Θ ( f )» см в обозначении Big O. .

Операция найти-мин удаление-мин вставлять клавиша уменьшения сливаться
Двоичный [12] я (1) Θ (логарифм n ) О (логарифм n ) О (логарифм n ) Θ ( н )
Левый я (1) Θ (логарифм n ) Θ (логарифм n ) О (логарифм n ) Θ (логарифм n )
Биномиальный [12] [13] я (1) Θ (логарифм n ) я (1) [а] Θ (логарифм n ) О (логарифм n )
Наклонный бином [14] я (1) Θ (логарифм n ) я (1) Θ (логарифм n ) О (логарифм n ) [б]
Сопряжение [3] я (1) О (логарифм n ) [а] я (1) о (логарифм n ) [а] [с] я (1)
Сопряжение по рангам [17] я (1) О (логарифм n ) [а] я (1) я (1) [а] я (1)
Фибоначчи [12] [18] я (1) О (логарифм n ) [а] я (1) я (1) [а] я (1)
Строгий Фибоначчи [19] я (1) О (логарифм n ) я (1) я (1) я (1)
Мостовая долина [20] [д] я (1) О (логарифм n ) я (1) я (1) я (1)
2–3 кучи [22] я (1) О (логарифм n ) [а] я (1) [а] я (1) О (логарифм n )
  1. ^ Перейти обратно: а б с д и ж г час я Амортизированное время.
  2. ^ в наихудшем случае Бродал и Окасаки описывают метод уменьшения сложности объединения до Θ (1); этот метод применим к любой структуре данных кучи, которая имеет вставку в Θ (1) и find-min , delete-min , объединение в O (log n ).
  3. ^ Нижняя граница [15] верхняя граница [16]
  4. ^ Бродал и Окасаки позже описывают постоянный вариант с теми же границами, за исключением клавиши уменьшения, которая не поддерживается.Кучи с n элементами могут быть построены снизу вверх за O ( n ). [21]

Ссылки [ править ]

  1. ^ Перейти обратно: а б с Фредман, Майкл Л .; Седжвик, Роберт ; Слитор, Дэниел Д .; Тарьян, Роберт Э. (1986). «Парная куча: новая форма саморегулирующейся кучи» (PDF) . Алгоритмика . 1 (1–4): 111–129. дои : 10.1007/BF01840439 . S2CID   23664143 .
  2. ^ Мельхорн, Курт ; Сандерс, Питер (2008). Алгоритмы и структуры данных: базовый набор инструментов (PDF) . Спрингер. п. 231.
  3. ^ Перейти обратно: а б с Яконо, Джон (2000), «Улучшенные верхние границы для спаривания куч», Proc. 7-й скандинавский семинар по теории алгоритмов (PDF) , Конспекты лекций по информатике, том. 1851, Springer-Verlag, стр. 63–77, arXiv : 1110.4428 , CiteSeerX   10.1.1.748.7812 , doi : 10.1007/3-540-44985-X_5 , ISBN  3-540-67690-2
  4. ^ Стаско, Джон Т .; Виттер, Джеффри С. (1987), «Сопряжение куч: эксперименты и анализ» (PDF) , Communications of the ACM , 30 (3): 234–249, CiteSeerX   10.1.1.106.2988 , doi : 10.1145/214748.214759 , S2CID   17811811
  5. ^ Фредман, Майкл Л. (1999). «Об эффективности объединения куч и связанных с ними структур данных» (PDF) . Журнал АКМ . 46 (4): 473–501. дои : 10.1145/320211.320214 . S2CID   16115266 . Архивировано из оригинала (PDF) 21 июля 2011 г. Проверено 3 мая 2011 г.
  6. ^ Перейти обратно: а б Петти, Сет (2005), «К окончательному анализу парных куч» (PDF) , Proc. 46-й ежегодный симпозиум IEEE по основам информатики (PDF) , стр. 174–183, doi : 10.1109/SFCS.2005.75 , ISBN  0-7695-2468-0 , S2CID   2717102
  7. ^ Элмасри, Амр (2009), «Сопряжение кучи с O (log log n ) снижает стоимость» (PDF) , Proc. 20-й ежегодный симпозиум ACM-SIAM по дискретным алгоритмам , стр. 471–476, CiteSeerX   10.1.1.502.6706 , doi : 10.1137/1.9781611973068.52
  8. ^ Эльмасри, Амр (ноябрь 2017 г.). «На пути к оптимальным саморегулирующимся отвалам» . Транзакции ACM на алгоритмах . 13 (4): 1–14. дои : 10.1145/3147138 . S2CID   1182235 .
  9. ^ Джонс, Дуглас В. (1986). «Эмпирическое сравнение реализаций очереди приоритетов и наборов событий». Коммуникации АКМ . 29 (4): 300–311. CiteSeerX   10.1.1.117.9380 . дои : 10.1145/5684.5686 . S2CID   43650389 .
  10. ^ Ларкин, Дэниел Х.; Сен, Сиддхартха; Тарьян, Роберт Э. (2014), «Эмпирическое исследование приоритетных очередей, возвращающееся к основам», Труды 16-го семинара по разработке алгоритмов и экспериментам , стр. 61–72, arXiv : 1403.0252 , doi : 10.1137/1.9781611973198. 7 , ISBN  978-1-61197-319-8 , S2CID   15216766
  11. ^ Чен, Мо; Чоудхури, Резаул Алам; Рамачандран, Виджая; Рош, Дэвид Лан; Тонг, Линлинг (12 октября 2007 г.). Приоритетные очереди и алгоритм Дейкстры (PDF) (Технический отчет). Техасский университет. ТР-07-54. {{cite tech report}}: CS1 maint: дата и год ( ссылка )
  12. ^ Перейти обратно: а б с д Кормен, Томас Х .; Лейзерсон, Чарльз Э .; Ривест, Рональд Л. (1990). Введение в алгоритмы (1-е изд.). MIT Press и McGraw-Hill. ISBN  0-262-03141-8 .
  13. ^ «Биномиальная куча | Блестящая вики по математике и естественным наукам» . блестящий.орг . Проверено 30 сентября 2019 г.
  14. ^ Бродал, Герт Столтинг; Окасаки, Крис (ноябрь 1996 г.), «Оптимальные чисто функциональные очереди приоритетов», Journal of Functional Programming , 6 (6): 839–857, doi : 10.1017/s095679680000201x
  15. ^ Фредман, Майкл Лоуренс (июль 1999 г.). «Об эффективности объединения куч и связанных структур данных» (PDF) . Журнал Ассоциации вычислительной техники . 46 (4): 473–501. дои : 10.1145/320211.320214 .
  16. ^ Петти, Сет (2005). К окончательному анализу парных куч (PDF) . FOCS '05 Материалы 46-го ежегодного симпозиума IEEE по основам информатики. стр. 174–183. CiteSeerX   10.1.1.549.471 . дои : 10.1109/SFCS.2005.75 . ISBN  0-7695-2468-0 .
  17. ^ Хёплер, Бернхард; Сен, Сиддхартха; Тарьян, Роберт Э. (ноябрь 2011 г.). «Кучи ранговых пар» (PDF) . СИАМ Дж. Компьютерные технологии . 40 (6): 1463–1485. дои : 10.1137/100785351 .
  18. ^ Фредман, Майкл Лоуренс ; Тарьян, Роберт Э. (июль 1987 г.). «Кучи Фибоначчи и их использование в улучшенных алгоритмах оптимизации сети» (PDF) . Журнал Ассоциации вычислительной техники . 34 (3): 596–615. CiteSeerX   10.1.1.309.8927 . дои : 10.1145/28869.28874 .
  19. ^ Бродал, Герт Столтинг ; Лагояннис, Джордж; Тарьян, Роберт Э. (2012). Строгие кучи Фибоначчи (PDF) . Материалы 44-го симпозиума по теории вычислений - STOC '12. стр. 1177–1184. CiteSeerX   10.1.1.233.1740 . дои : 10.1145/2213977.2214082 . ISBN  978-1-4503-1245-5 .
  20. ^ Бродал, Герт С. (1996), «Эффективные приоритетные очереди для наихудшего случая» (PDF) , Proc. 7-й ежегодный симпозиум ACM-SIAM по дискретным алгоритмам , стр. 52–58.
  21. ^ Гудрич, Майкл Т .; Тамассия, Роберто (2004). «7.3.6. Построение кучи снизу вверх». Структуры данных и алгоритмы в Java (3-е изд.). стр. 338–341. ISBN  0-471-46983-1 .
  22. ^ Такаока, Тадао (1999), Теория 2–3 куч (PDF) , стр. 12

Внешние ссылки [ править ]

Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: d83e582e92b8e603c51a30ad98b46331__1714036860
URL1:https://arc.ask3.ru/arc/aa/d8/31/d83e582e92b8e603c51a30ad98b46331.html
Заголовок, (Title) документа по адресу, URL1:
Pairing heap - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)