Priorità: Ho un'implementazione di un back-end LZSS generico C++ (disponibile here L'algoritmo di confronto utilizzato in questa versione è estremamente semplice, in quanto inizialmente doveva. comprimere file relativamente piccoli (al massimo 64kB) per hardware relativamente antico (in particolare, Mega Drive/Sega Genesis, dove 64kB è l'intera RAM principale)Risultati sovrapposte lookahead su LZ77/LZSS con alberi suffisso
Tuttavia, alcuni file impiegano troppo tempo per comprimersi sulla mia implementazione , nell'ordine dei minuti, il motivo è duplice: l'algoritmo di corrispondenza ingenuo impiega la maggior parte del tempo, ma ciò accade in particolare perché costruisco un grafico di compressione dal file per ottenere un calcolo ottimale sione. Guardando al profiler, la maggior parte del tempo viene speso alla ricerca di corrispondenze, sminuendo anche le dimensioni quadratiche del grafico risultante.
Da un po 'di tempo ho studiato diverse potenziali sostituzioni; uno che ha attirato la mia attenzione era dictionary-symbolwise flexible parsing using multilayer suffix trees. La parte multistrato è importante perché una delle varianti di LZSS che mi interessa utilizza codifiche di dimensione variabile per (posizione, lunghezza).
mio attuale implementazione permette partite nella finestra scorrevole di sovrapporre il buffer look-ahead, in modo che questo input:
aaaaaaaaaaaaaaaa
possono essere codificati direttamente come
(0,'a')(1,0,15)
invece di
(0,'a')(1,0,1)(1,0,2)(1,0,4)(1,0,8)
Qui, (0, 'a') significa codificare il carattere 'a' come letterale, mentre (1, n, m) significa 'copia m caratteri dalla posizione n '.
La domanda: Detto questo, ecco il mio problema: Ogni risorsa che ho trovato su alberi suffisso sembra implicare che non possono gestire il caso di sovrapposizione, e invece consente solo di trovare le partite che non si sovrappongono . Quando sono stati coinvolti gli alberi di suffisso, documenti di ricerca, libri e persino alcune implementazioni hanno fornito esempi di compressione senza sovrapposizione come se fossero una compressione perfetta (collegherei ad alcuni di questi ma la mia reputazione non lo consente). Alcuni hanno anche detto che le sovrapposizioni potrebbero essere utili quando si descrivono gli schemi di compressione di base, ma erano stranamente silenziosi sull'argomento quando si discutevano gli alberi dei suffissi.
Poiché l'albero del suffisso deve essere aumentato per archiviare comunque le informazioni di offset, sembra una proprietà che può essere verificata durante la ricerca di una corrispondenza: si eliminano le corrispondenze che iniziano nel buffer di previsione. E il modo in cui l'albero viene costruito/aggiornato significherebbe che se un fronte ti porta a un nodo che corrisponde a una partita che inizia con il look-ahead, restituisci il nodo precedente invece come qualsiasi altro discendente sarà anche sul look-ahead buffer.
Il mio approccio è errato o errato? Esiste un'implementazione o una discussione di LZ77/LZSS con alberi di suffisso che menzionano le corrispondenze che si sovrappongono al buffer look-ahead?
Non ho capito la prima parte. Se si dispone di un file di grandi dimensioni, si consiglia di tagliarlo in blocchi più piccoli, quindi ogni blocco non è più di 64 KB. Pertanto la tua semplice implementazione non dovrebbe rallentare esponenzialmente man mano che il file si ingrandisce. –
Non penso che stia rallentando così tanto in modo esponenziale quanto sta facendo scattare il caso peggiore; la corrispondenza semplice è * O * (* mn *) nel peggiore dei casi (m = lunghezza del pattern, n = lunghezza del testo cercato), e questo viene eseguito per ogni byte del file, quindi finisco con * O * (* mnp *) - questo tranne all'inizio e alla fine del file. La variante LZSS in questione ha un buffer di ricerca di 8192 byte (quindi * n * = 8192) e un buffer di previsione di 256 byte (quindi * m * = 256). Per un file di lunghezza * p *, il caso peggiore sarebbe * O * (2097152 * p *), che è più o meno ciò che viene osservato. – flamewing
Per divertenti modi di fare questo da altre fonti: https://github.com/mist64/pucrunch è piuttosto pericoloso. Maggiori informazioni qui: http://koti.kapsi.fi/a1bert/Dev/pucrunch/ –