A codificação de Huffman é um algoritmo de compressão de dados sem perdas . A codificação Huffman usa código de comprimento variável para representar um símbolo de origem (por exemplo, um caractere em um arquivo). O código é determinado a partir de uma estimativa das probabilidades de aparecimento dos símbolos fonte, sendo um código curto associado aos símbolos fonte mais frequentes.
Um código de Huffman é ótimo no sentido de menor comprimento para codificação de símbolo e uma distribuição de probabilidade conhecida. Métodos mais complexos de modelagem probabilística da fonte permitem obter melhores taxas de compressão.
Foi inventado por David Albert Huffman e publicado em 1952.
O princípio da codificação de Huffman é baseado na criação de uma estrutura em árvore composta por nós.
Suponha que a frase a ser codificada seja " este é um exemplo de uma árvore Huffman ". Primeiro, procuramos o número de ocorrências de cada personagem. No exemplo anterior, a frase contém 2 vezes o caractere he 7 espaços. Cada personagem constitui uma das folhas da árvore à qual associamos um peso igual ao seu número de ocorrências.
A árvore é criada da seguinte forma, associamos a cada vez os dois nós de menor peso, para dar um novo nó cujo peso é equivalente à soma dos pesos de seus filhos. Reiteramos esse processo até que tenhamos apenas um nó restante: a raiz. Então, por exemplo, o código 0 é associado a cada ramificação rodando à esquerda e o código 1 à direita.
Para obter o código binário de cada personagem, voltamos a árvore da raiz às folhas adicionando cada vez ao código um 0 ou um 1 dependendo do ramo seguido. A frase " este é um exemplo de uma árvore huffman " é então codificada em 135 bits em vez de 288 bits (se a codificação de caractere inicial for de 8 bits). É necessário começar pela raiz para obter os códigos binários, porque caso contrário, ao descompactar, começar pelas folhas pode causar confusão na decodificação.
Para codificar a " Wikipedia ", obtemos, portanto, em binário: 101 11 011 11 100 010 001 11 000, ou 24 bits em vez de 63 (9 caracteres x 7 bits por caractere) usando códigos ASCII (7 bits).
Existem três variações do algoritmo de Huffman, cada uma das quais define um método para criar a árvore:
Um código Huffman é o código-fonte . Para uma fonte , representada por uma variável aleatória , de distribuição de probabilidade , a expectativa do comprimento de um código é dada por
Onde está o comprimento da palavra de código, o código associado ao símbolo de origem e é o conjunto de símbolos de origem.
Um código Huffman é um código de prefixo com comprimento variável . É ideal, no sentido de comprimento mais curto, para codificação de símbolos . Ou seja, para um código Huffman e para qualquer código decodificável exclusivamente , então:
Podemos mostrar que, para uma fonte , a entropia de Shannon, o comprimento médio de uma palavra de código obtida pela codificação de Huffman satisfaz:
Esta relação mostra que a codificação de Huffman se aproxima da entropia da fonte, ou seja, do código ideal, mas isso pode de fato se revelar bastante desinteressante no caso em que a entropia da fonte é forte, e onde uma sobrecarga de 1 bit torna-se significativo. Além disso, a codificação de Huffman requer o uso de um número inteiro de bits para um símbolo de origem, o que pode ser ineficiente.
Uma solução para esse problema é trabalhar em blocos de símbolos. Em seguida, mostramos que podemos chegar mais perto da entropia:
mas o processo de estimar probabilidades torna-se mais complexo e caro.
Além disso, a codificação de Huffman não é adequada no caso de uma fonte cujas propriedades estatísticas mudam com o tempo, uma vez que as probabilidades dos símbolos mudam e a codificação se torna inadequada. A solução que consiste em re-estimar as probabilidades dos símbolos a cada iteração é impraticável devido à sua complexidade de tempo. A técnica então se torna a codificação Huffman adaptativa : para cada novo símbolo, a tabela de frequência é atualizada e a árvore de codificação modificada, se necessário. O descompressor fazendo o mesmo pelas mesmas causas ... permanece sincronizado com o que o compressor fez.
Na prática, quando queremos abordar a entropia, preferimos uma codificação aritmética que seja ótima no nível de bits.
Métodos mais complexos realizando uma modelagem probabilística da fonte e aproveitando esta redundância adicional tornam possível melhorar o desempenho de compressão deste algoritmo (ver LZ77 , predição por reconhecimento parcial , ponderação de contextos ).
Para que o mesmo conjunto de símbolos seja codificado, vários códigos de Huffman diferentes podem ser obtidos.
É possível transformar um código Huffman em um código Huffman canônico único para um determinado conjunto de símbolos de entrada. O princípio é inicialmente ordenar os símbolos em ordem lexical.
Nota: entre dois símbolos S1 e S2 que, em um código de Huffman específico, são codificados com o mesmo comprimento, são sempre codificados com o mesmo comprimento no código de Huffman canônico. No caso em que dois símbolos têm a mesma probabilidade e dois comprimentos de código diferentes, é possível que a passagem de um código de Huffman para um código de Huffman canônico modifique o comprimento desses códigos, a fim de garantir a atribuição do código. o primeiro símbolo em ordem lexicográfica.
A codificação Huffman é baseada apenas na frequência relativa dos símbolos de entrada (sequências de bits), sem distinção de sua origem (imagens, vídeos, sons, etc. ). Por isso, geralmente é utilizado no segundo estágio de compressão, uma vez que a redundância específica da mídia foi demonstrada por outros algoritmos. Pensa-se em particular na compressão JPEG para as imagens , MPEG para os vídeos e MP3 para o som , os quais podem remover os elementos supérfluos imperceptíveis aos humanos. Em seguida, falamos de compressão não conservadora (com perdas).
Outros algoritmos de compactação conservadores (sem perdas), como os usados para compactação de arquivos, também usam Huffman para compactar o dicionário resultante. Por exemplo, LZH ( Lha ) e deflate ( ZIP , gzip , PNG ) combinam um algoritmo de compressão de dicionário ( LZ77 ) e codificação de entropia de Huffman.
A codificação foi inventada por David Albert Huffman , durante sua tese de doutorado no MIT . O algoritmo foi publicado em 1952 no artigo Um Método para a Construção de Códigos de Redundância Mínima , nos Anais do Institute of Radio Engineers .
O primeiro Macintosh empresa Maçã usado um código com base Huffman para a representação de textos: os 15 caracteres mais frequentes de uma língua foram codificados em 4 bits, e o 16 th configuração serviu como um prefixo para a codificação de outro de byte único (que assim feito às vezes 4 bits, às vezes 12 bits por caractere, consulte UTF-8 ). Descobriu-se que esse método simples economiza 30% de espaço em um texto médio em um momento em que a RAM ainda era um componente caro.