Arbore palindrom

arbore palindrom
Engleză  copac

arbore palindrom pentru string eertree
Tip de structură de date
Anul inventiei 2015
Autor Mihail Rubinchik [d]
Complexitatea în simbolurile O
În cel mai rău caz
Clădire
Consumul de memorie
 Fișiere media la Wikimedia Commons

Un arbore palindromic ( eng.  palindromic tree , de asemenea overtree [1] , eng.  eertree ) este o structură de date concepută pentru a stoca și procesa subșiruri palindromice ale unui șir . A fost propus de oamenii de știință de la Universitatea Federală Ural Mikhail Rubinchik și Arseny Shur în 2015. Reprezintă doi arbori de prefix , asamblați din „jumătățile” din dreapta ale subșirurilor palindromice de lungime pară și, respectiv, impară. Structura ocupă memorie și poate fi construită în timp , unde  este lungimea șirului și  este numărul de caractere diferite din acesta. Cu ajutorul unui arbore palindrom, se pot rezolva în mod eficient probleme precum numărarea numărului de subșiruri palindromice diferite, găsirea împărțirii unui șir în cel mai mic număr de palindrom, verificarea dacă un subșir este un palindrom și altele.

Notație

Să fie  un șir și  să fie șirul inversat . Când descriem arborele palindrom al unui șir , se utilizează următoarea notație [2] :

Structura arborelui

În notația de mai sus, arborele palindrom al unui șir  este un grafic direcționat , fiecare vârf al căruia îi corespunde și este identificat cu un subpalindrom unic al șirului. Dacă șirul are subpalindromuri și , unde  este vreun caracter alfabetic , atunci arborele palindrom are un arc marcat cu simbolul , de la vârful corespunzător lui , până la vârful corespunzător lui . Într-un astfel de grafic, orice vârf poate avea doar un arc de intrare. Pentru comoditate, sunt introduse și două vârfuri auxiliare, care corespund palindromurilor de lungime ( șir goală ) și respectiv șir („imaginar”). Arcurile din șirul gol conduc la vârfuri corespunzătoare palindromurilor de forma , iar din „șirul imaginar” la vârfuri corespunzătoare palindromurilor formei (adică formate dintr-un singur caracter). Un vârf este numit chiar dacă are un palindrom de lungime pară, iar în caz contrar impar . Din definiție rezultă că arcurile dintr-un arbore palindrom trec numai între vârfuri cu aceeași paritate. Din punctul de vedere al arborilor de prefix, această structură poate fi descrisă după cum urmează [3] :

Vârfurile și arcurile arborelui palindrom formează doi arbori de prefix ale căror rădăcini sunt situate la vârfurile care definesc șirurile goale, respectiv „imaginare”. În acest caz, primul arbore de prefix este compus din jumătățile drepte ale subpalindromurilor de lungime pară, iar al doilea din cele impare.

Numărul de vârfuri din arborele palindrom nu depășește , ceea ce este o consecință directă a următoarei leme [4] :

Un șir de lungime poate avea cel mult subșiruri palindromice nevide distincte. Mai mult, după atribuirea unui anumit caracter la sfârșitul unui șir, numărul de subpalindromuri diferite ale acestui șir poate crește cu cel mult .

Dovada

Această afirmație rezultă din următoarele fapte:

  1. Dacă un palindrom este un sufix al unui palindrom , atunci este și prefixul acestuia;
  2. Dacă palindromurile și sunt sufixe ale șirului și , atunci apare de cel puțin două ori (ca prefix și ca sufix );
  3. Orice șir poate avea cel mult un sufix palindrom unic (care apare o singură dată).

Ultima proprietate este în esență echivalentă cu lema, deoarece toate subșirurile noi care apar la adăugarea următorului caracter la șir trebuie să fie sufixele acestuia [5] .

Pe lângă arcurile obișnuite care servesc drept tranziții pentru arborele de prefix, pentru fiecare vârf al arborelui palindrom este definită o legătură sufixă care duce de la vârf la vârful corespunzător celui mai mare sufix propriu (nu este egal cu întregul șir). palindrom . În același timp, legătura sufixului de la vârful „imaginar” nu este definită, dar prin definiție duce de la un vârf gol la cel „imaginar”. Legăturile sufixelor formează un arbore înrădăcinat la un vârf „imaginar” și joacă un rol important în construcția unui arbore palindrom [3] .

Clădire

La fel ca multe alte structuri de șir, un arbore palindrom este construit iterativ . Inițial, este format doar din vârfuri corespunzătoare șirurilor goale și imaginare. Structura este apoi reconstruită treptat pe măsură ce șirul crește câte un caracter. Deoarece cel mult un nou palindrom apare într-un șir la adăugarea unui caracter, reconstruirea arborelui în cel mai rău caz va necesita adăugarea unui nou nod și a unei legături de sufix la acesta. Pentru a determina un posibil nou nod în timpul construcției arborelui, se menține un ultim indicator către nodul corespunzător celui mai mare dintre sufixele palindromului actual [3] .

Toate sufixele-palindromele șirului sunt accesibile prin legături sufixe de la last , așa că pentru a determina un nou sufix-palindrom (va corespunde noului vârf, dacă există) este necesar să urmați legăturile sufixe ale ultimului până se constată că caracterul care precede sufixul-palindrom curent se potrivește cu caracterul care a fost atribuit șirului. Mai formal,  fie sufixul maxim palindrom al șirului , apoi fie , fie , unde  este un sufix palindrom . Astfel, iterând printre legăturile sufixe ale lui last , se poate determina dacă acesta poate fi extins prin compararea caracterelor și . Când a fost găsit sufixul palindrom corespunzător , ar trebui să verificați dacă arborele palindrom conține o tranziție de la vârful corespunzător prin simbolul [3] .

Dacă există o astfel de tranziție, atunci aceasta a fost deja întâlnită în linie mai devreme și corespunde vârfului la care duce această tranziție. În caz contrar, trebuie să creați un nou vârf pentru acesta și să faceți o tranziție de la . Apoi, definiți o legătură de sufix pentru care se potrivește cu al doilea cel mai lung sufix palindrom . Pentru a-l găsi, ar trebui să continuați să ocoliți ultimele legături sufixe până când este întâlnit al doilea vârf , astfel încât ; acest vârf va fi legătura sufixului . Dacă notăm tranziția de la vârf prin simbol ca , întregul proces poate fi descris prin următorul pseudocod [3] :

Funcția find_link(v): în timp ce s k -len(v)-1 ≠ s k : atribuiți v = link(v) return v funcția add_letter(c): atribuiți k = k + 1 define s k = c define q = find_link(last) dacă δ(q, c) nu este definit: define p = new_vertex() define len(p) = len(q ) + 2 definesc link(p) = δ(find_link(link(q)), c) defines δ(q, c) = p atribui ultimul = δ(q, c)

Se presupune aici că inițial arborele este descris doar de două vârfuri cu lungimi și, în consecință, cu o legătură sufixă de la primul vârf la al doilea. Ultima variabilă stochează vârful corespunzător celui mai mare sufix palindrom al liniei curente, inițial indică vârful liniei zero. De asemenea, se presupune că inițial este egal cu și în care este scris un caracter de serviciu, care nu apare în șirul .

Complexitate computațională

Complexitatea algoritmului poate varia în funcție de structurile de date care stochează tabelul de salt în arbore. În cazul general, când se folosește o matrice asociativă , timpul petrecut pentru accesare ajunge la , unde  este dimensiunea alfabetului din care este construit șirul. Este de remarcat faptul că fiecare iterație a primului apel la find_link reduce lungimea last , iar a celui de-al doilea, lungimea link(last) , care poate crește doar cu unul între apelurile succesive la add_letter . Astfel, timpul total al find_link nu depășește , iar timpul total necesar pentru a executa apelurile add_letter poate fi estimat ca [3] . Consumul de memorie al acestei structuri este liniar în cel mai rău caz, totuși, dacă luăm în considerare dimensiunea medie a structurii pe toate șirurile de o lungime dată , consumul mediu de memorie va fi de ordinul [6] .

Modificări

Concomitent cu introducerea acestei structuri de date, Rubinchik și Shur au propus și o serie de modificări care permit extinderea domeniului de aplicare a sarcinilor rezolvate de un arbore palindrom. În special, a fost propusă o metodă care permite construirea unui arbore palindrom general pentru un set de șiruri cu aceleași asimptotice . O astfel de modificare ne permite să rezolvăm aceleași probleme considerate în contextul unui set de șiruri - de exemplu, să găsim cel mai mare subpalindrom comun dintre toate șirurile sau numărul de subpalindromuri diferite ale tuturor șirurilor în agregat. O altă modificare propusă a fost o variantă de construcție a arborelui, în care adăugarea unui caracter necesită timp în cel mai rău caz (și nu amortizată , așa cum se întâmplă în construcția standard) și memorie. Această abordare face posibilă asigurarea persistenței parțiale a arborelui, în care este posibil să se anuleze adăugarea ultimului caracter în momente arbitrare. În plus, a fost propusă o versiune complet persistentă a arborelui, care vă permite să accesați și să adăugați un caracter la oricare dintre versiunile salvate anterior în timp și memorie în cel mai rău caz [7] .

În 2019, Watanabe și colegii au dezvoltat o structură de date bazată pe un arbore palindrom, numit e 2 rtre 2 , pentru a lucra cu subpalindromuri de șiruri date prin codificare run-length [4] , iar în 2020, aceeași echipă de autori, împreună cu Mieno, a dezvoltat doi algoritmi, care să permită menținerea unui arbore palindrom pe o fereastră glisantă de dimensiune . Primul dintre acești algoritmi necesită timp și memorie, iar al doilea necesită timp și memorie [8] .

Aplicații

Arborele palindrom oferă numeroase aplicații posibile pentru obținerea de algoritmi teoretic rapid și practic ușor de implementat pentru rezolvarea unui număr de probleme combinatorii în programare și cibernetică matematică [9] .

Una dintre sarcinile pentru care a fost dezvoltată această structură este de a număra diferite subpalindromuri într-un șir online . Poate fi setat după cum urmează: câte un caracter i se atribuie câte un caracter șirului inițial gol. La fiecare pas, trebuie să imprimați numărul de subpalindromuri diferite din șirul dat. Din punctul de vedere al arborelui palindrom, aceasta este echivalentă cu tipărirea numărului de vârfuri non-triviale din structură la fiecare pas. O soluție liniară pentru versiunea offline a acestei probleme a fost prezentată în 2010 [10] , iar soluția optimă cu timp de execuție pentru versiunea online a fost găsită în 2013 [11] . Cu toate acestea, soluția indicată a folosit două structuri de date „greu” - un analog al algoritmului Manaker , precum și un arbore de sufixe . Arborele palindrom, pe de o parte, are aceleași asimptotice în cel mai rău caz, iar pe de altă parte, este o structură mult mai ușoară [3] .

O altă posibilă aplicație a acestei structuri este enumerarea șirurilor binare bogate în palindrom [12] . Mai devreme s-a arătat că un cuvânt de lungime nu poate conține mai mult decât palindromuri diferite; cuvintele pe care se realizează această estimare sunt numite bogate în palindrom. Conceptul de cuvinte bogate în palindromic a fost introdus de Amy Glen și colegii săi în 2008 [13] . Rubinchik și Shur au arătat că folosind un arbore palindrom, se pot detecta toate cuvintele bogate în palindromic a căror lungime nu depășește , unde  este numărul acestor cuvinte. Acest rezultat a făcut posibilă creșterea numărului de membri cunoscuți ai secvenței A216264 în OEIS de la 25 la 60. Datele obținute au arătat că secvența crește mult mai lent decât se credea anterior, și anume, este mărginită de sus ca [14] .

Note

  1. Rubinchik, 2016 , p. 6-9
  2. Rubinchik, Shur, 2018 , pp. 1-2
  3. ↑ 1 2 3 4 5 6 7 Rubinchik, Shur, 2018 , pp. 2-6
  4. ↑ 1 2 Watanabe et al., 2019 , pp. 432-434
  5. Droubay și colab., 2001 , pp. 542-546
  6. Rubinchik, Shur, 2016 , p. unu
  7. Rubinchik, Shur, 2018 , p. 6-11
  8. Mieno și colab., 2020
  9. Rubinchik, 2016 , p. 75-76
  10. Groult, 2010
  11. Kosolobov et al., 2013
  12. Secvența OEIS A216264 _
  13. Glen și colab., 2009
  14. Rukavicka, 2017

Literatură

Link -uri