Suffix array - Suffix array

Suffix -array
Type Array
Opfundet af Manber & Myers (1990)
Tidskompleksitet
i stor O -notation
Gennemsnit Værste tilfælde
Plads
Konstruktion

Inden for datalogi er et suffiks array et sorteret array af alle suffikser i en streng . Det er en datastruktur, der blandt andet bruges i fuldtekstindekser, datakomprimeringsalgoritmer og bibliometriområdet .

Suffix -arrays blev introduceret af Manber & Myers (1990) som et simpelt, rumeffektivt alternativ til endetræer . De var uafhængigt blevet opdaget af Gaston Gonnet i 1987 under navnet PAT array ( Gonnet, Baeza-Yates & Snider 1992 ).

Li, Li & Huo (2016) gav den første tidssuffiks-array-konstruktionsalgoritme på stedet, der er optimal både i tid og rum, hvor in-place betyder, at algoritmen kun har brug for ekstra plads ud over inputstrengen og output-suffiks-arrayet.

Enhanced suffix arrays (ESA'er) er suffiksarrays med ekstra tabeller, der gengiver fuldfunktionaliteten af ​​suffixtræer, der bevarer samme tid og hukommelseskompleksitet. Endelsen array for en delmængde af alle suffikser i en streng kaldes sparsomt suffiks array . Flere probabilistiske algoritmer er blevet udviklet for at minimere den ekstra hukommelsesforbrug inklusive en optimal tids- og hukommelsesalgoritme.

Definition

Lad være en -streng og lad betegne delstrengen fra alt til inklusiv.

Endelsen vifte af nu defineret til at være et array af heltal leverer udgangspositioner suffikser af i leksikografisk rækkefølge . Dette betyder, en post indeholder startpositionen af th mindste suffiks i og dermed for alle : .

Hver endelse af shows op i præcis én gang. Suffikser er simple strenge. Disse strenge sorteres (som i en papirordbog), før deres startpositioner (heltalsindeks) gemmes i .

Eksempel

Overvej teksten = der skal indekseres: banana$

jeg 1 2 3 4 5 6 7
b -en n -en n -en $

Teksten slutter med det særlige vagtpostbrev, $der er unikt og leksikografisk mindre end nogen anden karakter. Teksten har følgende suffikser:

Tillæg jeg
banan $ 1
anana $ 2
nana $ 3
ana $ 4
efter $ 5
en $ 6
$ 7

Disse suffikser kan sorteres i stigende rækkefølge:

Tillæg jeg
$ 7
en $ 6
ana $ 4
anana $ 2
banan $ 1
efter $ 5
nana $ 3

Suffiksarrayet indeholder startpositionerne for disse sorterede suffikser:

jeg = 1 2 3 4 5 6 7
= 7 6 4 2 1 5 3

Suffiksarrayet med suffikserne skrevet lodret nedenunder for klarhedens skyld:

jeg = 1 2 3 4 5 6 7
= 7 6 4 2 1 5 3
1 $ -en -en -en b n n
2 $ n n -en -en -en
3 -en -en n $ n
4 $ n -en -en
5 -en n $
6 $ -en
7 $

Så indeholder for eksempel værdien 4, og refererer derfor til suffikset, der starter ved position 4 indenfor , som er suffikset . ana$

Korrespondance til suffiks træer

Suffix -arrays er nært beslægtet med suffix -træer :

  • Suffix-arrays kan konstrueres ved at udføre en dybde-første traversal af et suffix-træ. Suffiksarrayet svarer til bladetiketterne i den rækkefølge, hvor disse besøges under gennemgangen, hvis kanter besøges i leksikografisk rækkefølge af deres første karakter.
  • Et endetræ kan konstrueres i lineær tid ved hjælp af en kombination af endelse array og LCP array . For en beskrivelse af algoritmen, se det tilsvarende afsnit i LCP -arrayartiklen .

Det er blevet vist, at hver endelse -træ -algoritme systematisk kan erstattes med en algoritme, der bruger et suffiks -array, der er forbedret med yderligere information (f.eks. LCP -arrayet ) og løser det samme problem på samme tidskompleksitet. Fordele ved suffiksarrays frem for suffixtræer inkluderer forbedrede pladsbehov, enklere lineære tidsopbygningsalgoritmer (f.eks. Sammenlignet med Ukkonens algoritme ) og forbedret cachelokalitet.

Pladseffektivitet

Suffix -arrays blev introduceret af Manber & Myers (1990) for at forbedre pladsbehovet for suffix -træer : Suffix -arrays gemmer heltal. Forudsat at et helt tal kræver bytes, kræver et suffiksarray i alt bytes. Dette er betydeligt mindre end de bytes, der kræves af en omhyggelig implementering af suffiksetræ.

I visse applikationer kan pladsbehovet for suffiksarrays dog stadig være uoverkommeligt. Analyseret i bits kræver et suffiks array plads, mens den originale tekst over et alfabet i størrelse kun kræver bits. For et menneskeligt genom med og endelsen array ville derfor optage omkring 16 gange mere hukommelse end selve genomet.

Sådanne uoverensstemmelser motiverede en tendens til komprimerede suffiksarrays og BWT- baserede komprimerede fuldtekstindekser såsom FM-indekset . Disse datastrukturer kræver kun plads inden for tekstens størrelse eller endnu mindre.

Konstruktion algoritmer

Et endetræ kan bygges ind og kan konverteres til et suffiks array ved at krydse trædybden-først også i , så der findes algoritmer, der kan bygge et suffiks array i .

En naiv tilgang til at konstruere et suffiks array er at bruge en sammenligningsbaseret sorteringsalgoritme . Disse algoritmer kræver sammenligning af suffikser, men en suffiks sammenligning kører i tide, så den samlede driftstid af denne tilgang er .

Mere avancerede algoritmer drager fordel af, at de suffikser, der skal sorteres, ikke er vilkårlige strenge, men er relateret til hinanden. Disse algoritmer stræber efter at nå følgende mål:

  • minimal asymptotisk kompleksitet
  • let i rummet, hvilket betyder lidt eller ingen arbejdshukommelse ved siden af ​​teksten og selve endelsen array er nødvendig
  • hurtigt i praksis

En af de første algoritmer til at nå alle mål er SA-IS-algoritmen for Nong, Zhang & Chan (2009) . Algoritmen er også ret enkel (<100 LOC ) og kan forbedres til samtidig at konstruere LCP -arrayet . SA-IS-algoritmen er en af ​​de hurtigste kendte algoritmer til konstruktion af endelser. En omhyggelig implementering af Yuta Mori overgår de fleste andre lineære eller superlinjære konstruktionstilgange.

Foruden tid og rumkrav differentieres endelser til konstruktion af algoritmer også med deres understøttede alfabet : konstante alfabeter, hvor alfabetstørrelsen er bundet af en konstant, heltals alfabeter, hvor tegn er heltal i et område afhængigt af og generelle alfabeter, hvor kun tegn sammenligninger er tilladt .

De fleste algoritmer til konstruktion af suffiks -array er baseret på en af ​​følgende fremgangsmåder:

  • Præfiks -fordoblingsalgoritmer er baseret på en strategi fra Karp, Miller & Rosenberg (1972) . Ideen er at finde præfikser, der ærer den leksikografiske rækkefølge af suffikser. Den vurderede præfikslængde fordobles i hver iteration af algoritmen, indtil et præfiks er unikt og giver rangen til det tilhørende suffiks.
  • Rekursive algoritmer følger tilgangen til suffiks træbygningsalgoritmen af Farach (1997) for rekursivt at sortere en delmængde af suffikser. Denne delmængde bruges derefter til at udlede et suffiksarray af de resterende suffikser. Begge disse suffiksarrays flettes derefter for at beregne det endelige suffiksarray.
  • Inducerede kopieringsalgoritmer ligner rekursive algoritmer i den forstand, at de bruger et allerede sorteret undersæt til at fremkalde en hurtig slags af de resterende suffikser. Forskellen er, at disse algoritmer favoriserer iteration frem for recursion for at sortere det valgte endelsesundersæt. En undersøgelse af denne mangfoldige gruppe af algoritmer er blevet sammensat af Puglisi, Smyth & Turpin (2007) .

En velkendt rekursiv algoritme til heltalsalfabeter er DC3 / skæv algoritmen for Kärkkäinen & Sanders (2003) . Det kører i lineær tid og er med succes blevet brugt som grundlag for parallelle og eksterne hukommelsesuffiks -array -konstruktionsalgoritmer.

Nyligt arbejde af Salson et al. (2010) foreslår en algoritme til opdatering af suffikset array af en tekst, der er blevet redigeret i stedet for at genopbygge et nyt suffiks array fra bunden. Selvom den teoretiske værst tænkelige tidskompleksitet er , ser det ud til at fungere godt i praksis: eksperimentelle resultater fra forfatterne viste, at deres implementering af dynamiske suffiksarrays generelt er mere effektiv end genopbygning, når man overvejer at indsætte et rimeligt antal bogstaver i original tekst.

I praktisk open source- arbejde var en almindeligt anvendt rutine for endelse af arraykonstruktion qsufsort, baseret på Larsson-Sadakane-algoritmen fra 1999. Denne rutine er blevet afløst af Yuta Moris DivSufSort, "den hurtigste kendte endelse -sorteringsalgoritme i hovedhukommelsen" fra 2017. Den kan også ændres til at beregne et LCP -array. Den bruger en induceret kopiering kombineret med Itoh-Tanaka. I 2021 blev en hurtigere implementering af algoritmen præsenteret af Ilya Grebnov, som i gennemsnit viste 65% forbedring af ydelsen i forhold til DivSufSort -implementering på Silesia Corpus.

Generaliseret Suffix Array

Begrebet suffiks array kan udvides til mere end en streng. Dette kaldes et generaliseret suffiks array (eller GSA), et suffiks array, der indeholder alle suffikser for et sæt strenge (f.eks. Og er leksikografisk sorteret med alle suffikser i hver streng.

Ansøgninger

Endelsen af ​​en streng kan bruges som et indeks til hurtigt at lokalisere hver forekomst af et understrengsmønster i strengen . At finde hver forekomst af mønsteret svarer til at finde hvert suffiks, der begynder med delstrengen. Takket være den leksikografiske rækkefølge vil disse suffikser blive grupperet sammen i endelsen array og kan findes effektivt med to binære søgninger . Den første søgning finder intervallets startposition, og den anden bestemmer slutpositionen:

n = len(S)
def search(P: str) -> Tuple[int, int]:
    """
    Return indices (s, r) such that the interval A[s:r] (including the end
    index) represents all suffixes of S that start with the pattern P.
    """
    # Find starting position of interval
    l = 0  # in Python, arrays are indexed starting at 0
    r = n
    while l < r:
        mid = (l + r) // 2  # division rounding down to nearest integer
        # suffixAt(A[i]) is the ith smallest suffix
        if P > suffixAt(A[mid]):
            l = mid + 1
        else:
            r = mid
    s = l
    
    # Find ending position of interval
    r = n
    while l < r:
        mid = (l + r) // 2
        if suffixAt(A[mid]).startswith(P):
            l = mid + 1
        else:
            r = mid
    return (s, r)

Det tager tid at finde delstrengsmønsteret i længden i længden , da en sammenligning af enkelt suffiks skal sammenligne tegn. Manber & Myers (1990) beskriver, hvordan denne grænse kan forbedres til tid ved hjælp af LCP -oplysninger. Ideen er, at en mønstersammenligning ikke behøver at sammenligne visse tegn igen, når det allerede er kendt, at disse er en del af det længste fælles præfiks for mønsteret og det aktuelle søgeinterval. Abouelhoda, Kurtz & Ohlebusch (2004) forbedrer grænsen endnu mere og opnår en søgetid på som kendt fra suffiksetræer .

Suffiks -sorteringsalgoritmer kan bruges til at beregne Burrows – Wheeler -transformen (BWT) . Den BWT kræver sortering af alle cykliske permutationer af en streng. Hvis denne streng ender i et særligt slut-af-streng-tegn, der er leksikografisk mindre end alle andre tegn (dvs. $), svarer rækkefølgen af ​​den sorterede roterede BWT- matrix til rækkefølgen af ​​suffikser i et suffiksarray. Det BWT kan derfor beregnes i lineær tid ved først at konstruere et suffiks vifte af teksten og så udlede af BWT streng: .

Suffix-arrays kan også bruges til at slå op på substrater i eksempelbaseret maskinoversættelse , hvilket kræver meget mindre opbevaring end en hel sætningstabel som brugt i statistisk maskinoversættelse .

Mange yderligere applikationer af suffiks -arrayet kræver LCP -arrayet . Nogle af disse er detaljerede i sidstnævnte applikationsafsnit .

Noter

Referencer

eksterne links