Пређи на садржај

Упарујући хип — разлика између измена

С Википедије, слободне енциклопедије
Садржај обрисан Садржај додат
Autobot (разговор | доприноси)
м ciscenje
Нема описа измене
Ред 1: Ред 1:
{{МАТФ2015}}
{{МАТФ2015}}
Упарујући хип је тип структуре података са релативно једноставном имплементацијом као и са одличним, оптимизованим перформансама. Упарујући хипови су вишеструке структуре стабала, уређене хиповски и могу се сматрати поједностављеним Фибоначијевим хиповима. Сматрају се "грубим избором" за имплементацију алгоритама попут Примовог МСТ алгоритма и подржавају следеће операције <ref name="mehlhorn">{{cite book |last1=Mehlhorn|first1=Kurt|author1-link=Kurt Mehlhorn |first2=Peter |last2=Sanders|author2-link=Peter Sanders (computer scientist) |title=Algorithms and Data Structures: The Basic Toolbox |publisher=Springer |year=2008}}</ref>{{rp|231}} :
'''Упарујући хип''' је [[хип (структура података)|тип]] [[Структура података|структуре података]] са релативно једноставном имплементацијом као и са одличним, оптимизованим перформансама. Упарујући хипови су вишеструке структуре [[Стабло (структура података)|стабала]], уређене хиповски и могу се сматрати поједностављеним Фибоначијевим хиповима. Сматрају се "грубим избором" за имплементацију алгоритама попут [[Примов алгоритам|Примовог МСТ алгоритма]] и подржавају следеће операције <ref name="mehlhorn">{{cite book |last1=Mehlhorn|first1=Kurt|author1-link=Kurt Mehlhorn |first2=Peter |last2=Sanders|author2-link=Peter Sanders (computer scientist) |title=Algorithms and Data Structures: The Basic Toolbox |publisher=Springer |year=2008}}</ref>{{rp|231}} :
* '''find-min'''(пронађи минимум) : враћа елемнт са врха хипа.
* '''find-min'''(пронађи минимум) : враћа елемнет са врха хипа.
* '''merge(спајање)''': упоређује два елемента у корену, мањи елемент остаје корен резултата, док се већи елемент и његово подстабло додају као потомак тог корена.
* '''merge(спајање)''': упоређује два елемента у корену, мањи елемент остаје корен резултата, док се већи елемент и његово подстабло додају као потомак тог корена.
* '''insert(уметање)''': креирање новог хипа од унетог елемента и вршење merge операције над тим елементом са постојећим, оригиналним хипом.
* '''insert(уметање)''': креирање новог хипа од унетог елемента и вршење merge операције над тим елементом са постојећим, оригиналним хипом.
* '''decrease-key(смањење кључа)(опционално)''': уклања коренско подстабло чији се кључ смањује, замењује кључ са мањим кључем а затим се резултат након спајања враћа у хип.
* '''decrease-key(смањење кључа)(опционо)''': уклања коренско подстабло чији се кључ смањује, замењује кључ са мањим кључем а затим се резултат након спајања враћа у хип.
* '''delete-min(брисање минимума)''': уклања корен и спаја његова подстабла. Користи се више различитих стратегија.
* '''delete-min(брисање минимума)''': уклања корен и спаја његова подстабла. Користи се више различитих стратегија.


Анализа временске сложености упарујућих хипова је иницијално инспирисана "раширеним" стаблима.
Анализа временске сложености упарујућих хипова је иницијално инспирисана [[Раширено дрво|"раширеним" стаблима]]<ref name=FSST>{{cite journal
| last1 = Fredman | first1 = Michael L. | author1-link = Michael Fredman
Сложеност за delete-min износи <math> O(\log n) </math> . Операције find-min, merge, i insert се извршавају у константном времену, <math> O(1) </math>.
| last2 = Sedgewick | first2 = Robert | author2-link = Robert Sedgewick (computer scientist)
| last3 = Sleator | first3 = Daniel D. | author3-link = Daniel Sleator
| last4 = Tarjan | first4 = Robert E. | author4-link = Robert Tarjan
| doi = 10.1007/BF01840439
| issue = 1
| journal = Algorithmica
| pages = 111–129
| title = The pairing heap: a new form of self-adjusting heap
| url = http://www.cs.cmu.edu/~sleator/papers/pairing-heaps.pdf
| volume = 1
| year = 1986}}</ref>.
Сложеност за delete-min износи <math> O(\log n) </math> . Операције find-min, merge, i insert се извршавају у константном времену, <math> O(1) </math><ref name=Iacono2>{{cite conference
| last = Iacono | first = John
| title = Improved upper bounds for pairing heaps
| url = http://john2.poly.edu/papers/swat00/paper.pdf
| doi = 10.1007/3-540-44985-X_5
| pages = 63–77
| publisher = Springer-Verlag
| series = Lecture Notes in Computer Science
| conference = Proc. 7th Scandinavian Workshop on Algorithm Theory
| volume = 1851
| year = 2000
| isbn = 978-3-540-67690-4
| arxiv = 1110.4428 }}</ref>.


Испоставило се да је израчунавање прецизног асимптотског времена извршавања упарујућих хипова када је потребна decrease-key операција, компликовано. Нагађа се да је временска сложеност ове операције <math> O(1) </math>, али је Фредман доказао да је временска сложеност бар <math> \Omega(\log\log n)</math>. Пети је онда извео горњу границу која je <math> O(2^{2\sqrt{\log\log n}}) </math>, оптимизовано време за decrease-key износи <math> O(\log n) </math> .
Испоставило се да је израчунавање прецизног асимптотског времена извршавања упарујућих хипова када је потребна decrease-key операција, компликовано. Нагађа се да је временска сложеност ове операције <math> O(1) </math><ref name=StaskoVitter>{{citation
| last1 = Stasko | first1 = John T. | author-link = John Stasko

| last2 = Vitter | first2 = Jeffrey S. | author2-link = Jeffrey Vitter
Иако је ово лошија сложеност у поређењу са другим "priority queue" алгоритмима као што су Фибоначијеви хипови, где је сложеност decrease-key <math> O(1) </math> , перформанса у пракси је изванредна. Стаско, Витер, Морет и Шапиро су спровели експеримент над упарујућим хиповима и другим хип структурама података. Дошли су до закључка да су упарујући хипови бар подједнако брзи али у већини случајева и бржи у поређењу са другим ефикасним структурама података као што су бинарни хипови.
| doi = 10.1145/214748.214759
| issue = 3
| journal = Communications of the ACM
| pages = 234–249
| title = Pairing heaps: experiments and analysis
| id = {{citeseerx|10.1.1.106.2988}}
| volume = 30
| year = 1987}}</ref>, али је Фредман доказао да је временска сложеност бар <math> \Omega(\log\log n)</math><ref name=Fredman>{{cite journal
| last = Fredman | first = Michael L. | author-link = Michael Fredman
| doi = 10.1145/320211.320214
| issue = 4
| journal = Journal of the ACM
| pages = 473–501
| title = On the efficiency of pairing heaps and related data structures
| url = http://wwwens.uqac.ca/azinflou/Fichiers840/EfficiencyPairingHeap.pdf
| volume = 46
| year = 1999}}</ref>. Пети је онда извео горњу границу која je <math> O(2^{2\sqrt{\log\log n}}) </math>, оптимизовано време за decrease-key износи <math> O(\log n) </math><ref name=Pettie>{{citation
| last = Pettie | first = Seth
| contribution = Towards a final analysis of pairing heaps
| doi = 10.1109/SFCS.2005.75
| contribution-url = http://www.eecs.umich.edu/~pettie/papers/focs05.pdf
| pages = 174–183
| title = [[Symposium on Foundations of Computer Science|Proc. 46th Annual IEEE Symposium on Foundations of Computer Science]]
| year = 2005
| isbn = 0-7695-2468-0}}</ref>.


Иако је ово лошија сложеност у поређењу са другим "priority queue" алгоритмима као што су Фибоначијеви хипови, где је сложеност decrease-key <math> O(1) </math> , перформанса у пракси је изванредна. Стаско, Витер<ref name=StaskoVitter/>, Морет и Шапиро<ref name=MoretShapiro>{{citation
| last1 = Moret | first1 = Bernard M. E.
| last2 = Shapiro | first2 = Henry D.
| contribution = An empirical analysis of algorithms for constructing a minimum spanning tree
| id = {{citeseerx|10.1.1.53.5960}}
| doi = 10.1007/BFb0028279
| pages = 400–411
| publisher = Springer-Verlag
| series = Lecture Notes in Computer Science
| title = [[Workshop on Algorithms and Data Structures|Proc. 2nd Workshop on Algorithms and Data Structures]]
| volume = 519
| year = 1991
| isbn = 3-540-54343-0}}</ref> су спровели експеримент над упарујућим хиповима и другим хип структурама података. Дошли су до закључка да су упарујући хипови бар подједнако брзи али у већини случајева и бржи у поређењу са другим ефикасним структурама података као што су бинарни хипови.


== Структура ==
== Структура ==
Ред 21: Ред 83:
'''type''' PairingHeap[Elem] = Empty | Heap(elem: Elem, subheaps: List[PairingHeap[Elem]])
'''type''' PairingHeap[Elem] = Empty | Heap(elem: Elem, subheaps: List[PairingHeap[Elem]])


Имплементација РАМ машина базирана на показивачима која подржава decrease-key може бити постигнута коришћењем три показивача по чвору, представљајући потомка чвора као једноструко повезану листу; показивач на први потомак чвора, један на његовог блиског/суседног рођака (енг. sibling) и један на његовог родитеља. Алтернатива је да показивач на родитеља буде изостављен, последњи потомак ће показивати на родитеља ако се дода заставица која ће означавати крај листе. Овиме се постиже компактнија структура по цену константног фактора по операцији.
Имплементација РАМ машина базирана на показивачима која подржава decrease-key може бити постигнута коришћењем три показивача по чвору, представљајући потомка чвора као једноструко повезану листу; показивач на први потомак чвора, један на његовог блиског/суседног рођака (енг. sibling) и један на његовог родитеља. Алтернатива је да показивач на родитеља буде изостављен, последњи потомак ће показивати на родитеља ако се дода заставица која ће означавати крај листе. Овиме се постиже компактнија структура по цену константног фактора по операцији<ref name="FSST"/>.


== Операције ==
== Операције ==
Ред 28: Ред 90:


функција find-min једноставно вража коренски елемент хипа.
функција find-min једноставно вража коренски елемент хипа.



'''function''' find-min(heap)
'''function''' find-min(heap)
Ред 35: Ред 96:
'''else'''
'''else'''
'''return''' heap.elem
'''return''' heap.elem



=== merge(спајање) ===
=== merge(спајање) ===


Спајање са празним хипом враћа други хип, иначе враћа нови хип који као коренски елемент има минимум од два коренска елемента и само додаје хип са већим кореном у листу под-хипова.<ref name=Fredman>{{cite journal
Спајање са празним хипом враћа други хип, иначе враћа нови хип који као коренски елемент има минимум од два коренска елемента и само додаје хип са већим кореном у листу под-хипова.<ref name=Fredman/>
|last=Fredman| first = Michael L. | author-link = Michael Fredman
| doi = 10.1145/320211.320214
| issue = 4
| journal = Journal of the ACM
| pages = 473–501
| title = On the efficiency of pairing heaps and related data structures
| url = http://wwwens.uqac.ca/azinflou/Fichiers840/EfficiencyPairingHeap.pdf
| volume = 46
| year = 1999}}</ref>


'''function''' merge(heap1, heap2)
'''function''' merge(heap1, heap2)
Ред 59: Ред 110:
'''else'''
'''else'''
'''return''' Heap(heap2.elem, heap1 :: heap2.subheaps)
'''return''' Heap(heap2.elem, heap1 :: heap2.subheaps)



=== insert(Уметање) ===
=== insert(Уметање) ===
Ред 67: Ред 117:
'''function''' insert(elem, heap)
'''function''' insert(elem, heap)
'''return''' merge(Heap(elem, []), heap)
'''return''' merge(Heap(elem, []), heap)



=== delete-min(брисање минимума) ===
=== delete-min(брисање минимума) ===
Ред 78: Ред 127:
'''else'''
'''else'''
'''return''' merge-pairs(heap.subheaps)
'''return''' merge-pairs(heap.subheaps)



Користимо помоћну функцију merge-pairs(спајање парова):
Користимо помоћну функцију merge-pairs(спајање парова):
Ред 89: Ред 137:
'''else'''
'''else'''
'''return''' merge(merge(l[0], l[1]), merge-pairs(l[2.. ]))
'''return''' merge(merge(l[0], l[1]), merge-pairs(l[2.. ]))



Испод је приказано да је ово заиста имплементирано као у опису изнад, односно као два пролаза, са лева у десно и са десна у лево.
Испод је приказано да је ово заиста имплементирано као у опису изнад, односно као два пролаза, са лева у десно и са десна у лево.
Ред 107: Ред 154:
# finally, merge the first merged pair with the result of merging the rest
# finally, merge the first merged pair with the result of merging the rest
=> '''H1234567'''
=> '''H1234567'''




== Референце ==
== Референце ==
{{reflist|50em}}

{{reflist}}

== Литература ==


== Спољашње везе ==
== Спољашње везе ==

Верзија на датум 28. март 2016. у 12:45

Упарујући хип је тип структуре података са релативно једноставном имплементацијом као и са одличним, оптимизованим перформансама. Упарујући хипови су вишеструке структуре стабала, уређене хиповски и могу се сматрати поједностављеним Фибоначијевим хиповима. Сматрају се "грубим избором" за имплементацију алгоритама попут Примовог МСТ алгоритма и подржавају следеће операције [1]:231 :

  • find-min(пронађи минимум) : враћа елемнет са врха хипа.
  • merge(спајање): упоређује два елемента у корену, мањи елемент остаје корен резултата, док се већи елемент и његово подстабло додају као потомак тог корена.
  • insert(уметање): креирање новог хипа од унетог елемента и вршење merge операције над тим елементом са постојећим, оригиналним хипом.
  • decrease-key(смањење кључа)(опционо): уклања коренско подстабло чији се кључ смањује, замењује кључ са мањим кључем а затим се резултат након спајања враћа у хип.
  • delete-min(брисање минимума): уклања корен и спаја његова подстабла. Користи се више различитих стратегија.

Анализа временске сложености упарујућих хипова је иницијално инспирисана "раширеним" стаблима[2]. Сложеност за delete-min износи . Операције find-min, merge, i insert се извршавају у константном времену, [3].

Испоставило се да је израчунавање прецизног асимптотског времена извршавања упарујућих хипова када је потребна decrease-key операција, компликовано. Нагађа се да је временска сложеност ове операције [4], али је Фредман доказао да је временска сложеност бар [5]. Пети је онда извео горњу границу која je , оптимизовано време за decrease-key износи [6].

Иако је ово лошија сложеност у поређењу са другим "priority queue" алгоритмима као што су Фибоначијеви хипови, где је сложеност decrease-key , перформанса у пракси је изванредна. Стаско, Витер[4], Морет и Шапиро[7] су спровели експеримент над упарујућим хиповима и другим хип структурама података. Дошли су до закључка да су упарујући хипови бар подједнако брзи али у већини случајева и бржи у поређењу са другим ефикасним структурама података као што су бинарни хипови.

Структура

Упарујући хипови су или празни хипови или пар који се састоји од коренског елемента и вероватно празном листом упарујућих хипова. Особина уређења хипа захтева да сви коренски елементи под-хипова у листи не буду мањи од коренског елемента хипа. У опису који следи претпоставља се да је реч о чисто функционалном хипу који не подржава decrease-key операцију.

type PairingHeap[Elem] = Empty | Heap(elem: Elem, subheaps: List[PairingHeap[Elem]])

Имплементација РАМ машина базирана на показивачима која подржава decrease-key може бити постигнута коришћењем три показивача по чвору, представљајући потомка чвора као једноструко повезану листу; показивач на први потомак чвора, један на његовог блиског/суседног рођака (енг. sibling) и један на његовог родитеља. Алтернатива је да показивач на родитеља буде изостављен, последњи потомак ће показивати на родитеља ако се дода заставица која ће означавати крај листе. Овиме се постиже компактнија структура по цену константног фактора по операцији[2].

Операције

find-min(пронађи минимум)

функција find-min једноставно вража коренски елемент хипа.

function find-min(heap)
  if heap == Empty
    error
  else
    return heap.elem

merge(спајање)

Спајање са празним хипом враћа други хип, иначе враћа нови хип који као коренски елемент има минимум од два коренска елемента и само додаје хип са већим кореном у листу под-хипова.[5]

function merge(heap1, heap2)
  if heap1 == Empty
    return heap2
  elsif heap2 == Empty
    return heap1
  elsif heap1.elem < heap2.elem
    return Heap(heap1.elem, heap2 :: heap1.subheaps)
  else
    return Heap(heap2.elem, heap1 :: heap2.subheaps)

insert(Уметање)

Најједноставнији начин уметања елемента у хип је спајање хипа са новим хипом који садржи само жељени елемент и празну листу под-хипова.

function insert(elem, heap)
  return merge(Heap(elem, []), heap)

delete-min(брисање минимума)

Једина нетривијална фундаментална операција је брисање минималног елемнта хипа. Стандардна стратегија је да се прво споје подхипови у парове (по овом кораку је структура добила име упарујући хипови) са лева у десно а затим спаја листу хипова са десна у лево.

function delete-min(heap)
  if heap == Empty
    error
  else
    return merge-pairs(heap.subheaps)

Користимо помоћну функцију merge-pairs(спајање парова):

function merge-pairs(l)
  if length(l) == 0
    return Empty
  elsif length(l) == 1
    return l[0]
  else
    return merge(merge(l[0], l[1]), merge-pairs(l[2.. ]))

Испод је приказано да је ово заиста имплементирано као у опису изнад, односно као два пролаза, са лева у десно и са десна у лево.

   merge-pairs([H1, H2, H3, H4, H5, H6, H7])
=> merge(merge(H1, H2), merge-pairs([H3, H4, H5, H6, H7]))
     # merge H1 and H2 to H12, then the rest of the list
=> merge(H12, merge(merge(H3, H4), merge-pairs([H5, H6, H7])))
     # merge H3 and H4 to H34, then the rest of the list
=> merge(H12, merge(H34, merge(merge(H5, H6), merge-pairs([H7]))))
     # merge H5 and H6 to H56, then the rest of the list
=> merge(H12, merge(H34, merge(H56, H7)))
     # switch direction, merge the last two resulting heaps, giving H567
=> merge(H12, merge(H34, H567))
     # merge the last two resulting heaps, giving H34567
=> merge(H12, H34567) 
     # finally, merge the first merged pair with the result of merging the rest
=> H1234567

Референце

  1. ^ Mehlhorn, Kurt; Sanders, Peter (2008). Algorithms and Data Structures: The Basic Toolbox. Springer. 
  2. ^ а б Fredman, Michael L.; Sedgewick, Robert; Sleator, Daniel D.; Tarjan, Robert E. (1986). „The pairing heap: a new form of self-adjusting heap” (PDF). Algorithmica. 1 (1): 111—129. doi:10.1007/BF01840439. 
  3. ^ Iacono, John (2000). Improved upper bounds for pairing heaps (PDF). Proc. 7th Scandinavian Workshop on Algorithm Theory. Lecture Notes in Computer Science. 1851. Springer-Verlag. стр. 63—77. ISBN 978-3-540-67690-4. arXiv:1110.4428Слободан приступ. doi:10.1007/3-540-44985-X_5. 
  4. ^ а б Stasko, John T.; Vitter, Jeffrey S. (1987), „Pairing heaps: experiments and analysis”, Communications of the ACM, 30 (3): 234—249, doi:10.1145/214748.214759, CiteSeerX: 10.1.1.106.2988 
  5. ^ а б Fredman, Michael L. (1999). „On the efficiency of pairing heaps and related data structures” (PDF). Journal of the ACM. 46 (4): 473—501. doi:10.1145/320211.320214. 
  6. ^ Pettie, Seth (2005), „Towards a final analysis of pairing heaps” (PDF), Proc. 46th Annual IEEE Symposium on Foundations of Computer Science, стр. 174—183, ISBN 0-7695-2468-0, doi:10.1109/SFCS.2005.75 
  7. ^ Moret, Bernard M. E.; Shapiro, Henry D. (1991), „An empirical analysis of algorithms for constructing a minimum spanning tree”, Proc. 2nd Workshop on Algorithms and Data Structures, Lecture Notes in Computer Science, 519, Springer-Verlag, стр. 400—411, ISBN 3-540-54343-0, doi:10.1007/BFb0028279, CiteSeerX: 10.1.1.53.5960 

Спољашње везе