Nessun algoritmo di compressione può comprimere tutti i messaggi di input?


8

Ho appena iniziato a leggere un libro intitolato Introduzione alla compressione dei dati, di Guy E. Blelloch. Nella prima pagina, afferma:

La verità è che se un singolo messaggio viene abbreviato da un algoritmo, allora alcuni altri messaggi devono essere allungati. Puoi verificarlo in pratica eseguendo GZIP su un file GIF. È infatti possibile andare oltre e mostrare che per un insieme di messaggi di input di lunghezza fissa, se un messaggio è compresso, la lunghezza media dei messaggi compressi su tutti gli input possibili sarà sempre più lunga dell'originale messaggi di input.

Consideriamo, ad esempio, gli 8 possibili messaggi a 3 bit. Se uno è compresso a due bit, non è difficile convincersi che due messaggi dovranno espandersi a 4 bit, dando una media di 3 1/8 bit.

Veramente? Trovo molto difficile convincermi di ciò. In effetti, ecco un contro esempio. Si consideri l'algoritmo che accetta come input qualsiasi stringa a 3 bit e si associa ai seguenti output:

000 -> 0
001 -> 001
010 -> 010
011 -> 011
100 -> 100 
101 -> 101
110 -> 110
111 -> 111

Quindi eccoti: nessun input è mappato su un output più lungo. Non ci sono certamente "due messaggi" che si sono espansi a 4 bit.

Quindi di cosa parla esattamente l'autore? Ho il sospetto che ci sia qualche avvertimento implicito che per me non è ovvio, oppure sta usando un linguaggio troppo vasto.

Disclaimer: mi rendo conto che se il mio algoritmo viene applicato in modo iterativo, perdi davvero i dati. Prova ad applicarlo due volte all'ingresso 110: 110 -> 000 -> 0, e ora non sai quale tra 110 e 000 era l'input originale. Tuttavia, se lo applichi solo una volta, mi sembra senza perdite. È legato a ciò di cui parla l'autore?


13
Il tuo codice non è un codice. Come intendete decodificare 00010?

3
In realtà, esiste una prova molto semplice di questo fatto che si basa sul principio del buco del piccione. en.wikipedia.org/wiki/…
chazisop,

Se è possibile comprimere ogni messaggio a 3 bit in <= 3 bit, è possibile comprimere il messaggio infinitamente lungo in pochi bit. ad es. se la tua proposta funzionasse, allora potresti semplicemente xor con il valore a 3 bit più ricorrente, aggiungere il valore all'inizio e comprimerlo. quindi continua a ripetere fino a quando un messaggio richiede solo pochi bit.
JarkkoL,

Risposte:


16

Quello che ti manca è che devi considerare tutti i bit di dimensione 3 o meno . Cioè: se in uno schema di compressione per bit di dimensione 3 o inferiore comprimiamo una delle stringhe a 3 bit in una stringa a 2 bit, allora una stringa di dimensione 3 o inferiore dovrà espandersi a 3 bit o più.

Uno schema di compressione senza perdita è una funzione C da stringhe di bit finite a stringhe di bit finite che è iniettivo, cioè se C(x)=C(y) poi x=ycioè C(x) determina in modo univoco x.

Prendi in considerazione uno schema di compressione arbitrario C e lascia Sessere un insieme di stringhe binarie. Possiamo esprimere quanto beneC funziona su S calcolando il rapporto

Rapporto di compressione(C,S)=ΣXSlength(C(X))ΣXSlength(X).
Un piccolo rapporto di compressione è buono. Ad esempio, se lo è1/2 ciò significa che in media possiamo comprimere le stringhe S del 50% utilizzando C.

Se proviamo a comprimere al massimo tutte le stringhe di lunghezzan allora siamo nei guai:

Teorema: LetSessere l'insieme di tutte le stringhe di lunghezza al massimon e Cqualsiasi schema di compressione. PoiRapporto di compressione(C,S)1.

Quindi, il miglior schema di compressione al mondo è la funzione identità! Bene, solo se vogliamo comprimere stringhe casuali di bit. Le stringhe di bit che si verificano in pratica sono tutt'altro che casuali e mostrano molta regolarità. Questo è il motivo per cui ha senso comprimere i dati nonostante il teorema di cui sopra.


Grazie. Quindi l'autore sbaglia, vero? Ha detto "messaggi di lunghezza fissa" e "considera gli 8 messaggi a 3 bit", ma avrebbe dovuto dire "messaggi di lunghezza massima fissa" e "considera i 14 possibili messaggi al massimo di 3 bit"?
Jack M,

@JackM: o meglio: "considera tutte le stringhe di lunghezza al massimo 3 rispetto all'alfabeto {0,1}"
Vor,

7

Solo una nota aggiuntiva alla buona risposta di Andrej:

Puoi anche dare un'occhiata alla complessità di Kolmogorov :

Definizione : data una stringaS, la sua complessità di Kolmogorov C(S) rispetto a un modello fisso di calcolo è la lunghezza del programma di cortocircuiti (ad es. macchina di Turing) che emette S.

senza formalità C(S)misura il contenuto delle informazioni o il grado di ridondanza ; una stringaSè incomprimibile seC(S)|S|

Due teoremi fondamentali sono:

1) indipendentemente dal modello di calcolo esiste una costante c tale che per ogni stringa S: C(S)|S|+c (informalmente, data una stringa S puoi codificarlo duramente in un programma che lo emette semplicemente senza elaborazione o compressione)

2) per tutti n esiste una stringa S di lunghezza n che è incomprimibile: C(S)|S| (analogo al teorema descritto nella risposta di Andrej).

La prova è semplice: ci sono 2n stringhe binarie di lunghezza n, ma meno descrizioni (programmi) di lunghezza <n:

Σio=0n-12io=2n-1<2n.


4

Il tuo controesempio è sbagliato.

Il tuo elenco di valori compressi contiene alcune informazioni nascoste che in effetti rendono la lunghezza media più lunga di 3 bit. Le informazioni extra sono la lunghezza della stringa di output.

Con i nostri occhi possiamo vedere dalla tua tabella che la prima stringa di output è lunga solo 1 bit e le altre sono 3 bit, ma stai barando se non codifichi esplicitamente quel fatto. Codifichiamolo anteponendo un altro bit; 0 significa "lunghezza = 1" e 1 significa "lunghezza = 3".

Quindi il tuo tavolo diventa davvero:

000 -> 00
001 -> 1001
010 -> 1010
011 -> 1011
100 -> 1100 
101 -> 1101
110 -> 1110
111 -> 1111

... che è in media di 3,75 bit.

MODIFICARE

Ecco un ripensamento, che illustra lo stesso punto. È una bella domanda a quiz:

Il codice Morse è composto da soli punti e trattini. Chiamiamo punto 0 e trattino 1. Tutte le lettere maiuscole sono codificate come non più di quattro bit.

E = . = 0
Q = --.- = 1101

Ci sono 26 lettere maiuscole. Ma quattro bit dovrebbero essere in grado di codificare solo 16 valori distinti. Cosa sta succedendo?


È davvero necessario? Mi sembra che in alcune situazioni sia perfettamente ragionevole permettere che la lunghezza sia implicita, come se si avesse un protocollo in cui OGNI messaggio è preceduto dalla sua lunghezza codificata come una parola a larghezza fissa. Dal momento che precede ogni messaggio, compresso o meno, può essere trascurato. E il post di Andrej risponde alla domanda lasciando implicita la lunghezza, quindi la tua limitazione sembra superflua. Ancora un buon punto per essere sollevato in entrambi i modi, ovviamente.
Jack M

In realtà, pensi che forse la tua restrizione alla necessità di codificare esplicitamente la lunghezza sia equivalente alla restrizione di Andrej alla necessità di codificare tutte le stringhe di meno di 3 bit?
Jack M,

@JackM: Nella maggior parte dei casi, verrà utilizzato uno schema di compressione non solo per mappare singoli pezzi di dati su altri singoli pezzi (si spera più piccoli), ma piuttosto per mappare sequenze di pezzi di dati su altre sequenze di pezzi (si spera più brevi) di dati. Se le sequenze di input sono tutte in un singolo flusso che include informazioni sufficienti per suddividerle, la "lunghezza di input" dovrebbe includere tutte le informazioni necessarie per analizzare l'input da un singolo stream e la "lunghezza di output" dovrebbe includere tutte le informazioni necessarie per analizzare l'output.
Supercat,

0

Contando il banale caso di lunghezza zero, ci sono 2n+1-1stringhe di bit la cui lunghezza è al massimo n (se si sa che le lunghezze sono multipli esatti di otto, il numero è più piccolo ma più difficile da calcolare). Pertanto, tutte le stringhe di lunghezzan o meno potrebbe essere rappresentato usando stringhe di lunghezza fissa n+1. Se molte stringhe saranno molto più brevi della lunghezza massima, tuttavia, può essere utile utilizzare schemi di codifica alternativi che aggiungono più di una alla lunghezza delle stringhe massime, ma inferiore alla lunghezza delle stringhe più brevi. Di conseguenza, la quantità di informazioni trasmesse conoscendo la lunghezza esatta di una stringa dipende da quanto tempo si potrebbe presumere che la stringa potrebbe essere e da quanto si sarebbe disposti a riempire stringhe più brevi.

Poiché tali fattori dipendono in larga misura dall'applicazione, è utile assumere un modello di calcolo in cui si presume che le stringhe di input contengano informazioni che sarebbero sufficienti a far sapere a un lettore dove finiscono (anche se sono state riempite con quantità arbitrarie di dati arbitrari) e le stringhe di output devono fare altrettanto. Tale modello di calcolo consentirà a tutte le operazioni che dovrebbero funzionare su singoli record di dati di funzionare anche su qualsiasi sequenza concatenata di record di dati [si può presumere che il codice che saprebbe quando interrompere la lettura di interi record non compressi sappia quando fermarsi lettura di quelli interi compressi].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.